Skip to content

pinHeader pinCount accepts fractional, zero, negative and infinite values #756

Description

@DPS0340

Summary

pinHeaderProps.pinCount is declared as a bare z.number(), so it accepts fractional, zero, negative and infinite values. A fractional count produces a header whose port count and pad count disagree, and nothing reports it.

<board width="30mm" height="30mm">
  <pinheader name="H1" pinCount={2.5} pcbX={0} pcbY={0} />
</board>
pinCount source_ports pads errors
2 2 2 0
2.5 2 3 0
3 3 3 0
3.7 3 4 0
4 4 4 0

Every whole number agrees. Every fractional one produces a component with a pad that has no port behind it — the same shape of defect as a phantom pin, and it renders and exports without complaint.

Zero and negative counts fail too, just later and less clearly:

pinCount=-4  →  0 ports, 0 pads, 1 error: pcb_missing_footprint_error
pinCount=0   →  0 ports, 0 pads, 1 error: pcb_missing_footprint_error

pcb_missing_footprint_error points at the footprint. The mistake was the pin count.

At the schema level:

pinHeaderProps.safeParse({ name: "H1", pinCount: 2.5 })        // success ✅
pinHeaderProps.safeParse({ name: "H1", pinCount: -4 })         // success ✅
pinHeaderProps.safeParse({ name: "H1", pinCount: 0 })          // success ✅
pinHeaderProps.safeParse({ name: "H1", pinCount: Infinity })   // success ✅

(NaN is already rejected — zod's z.number() excludes it but not Infinity.)

Cause

lib/components/pin-header.ts:

export const pinHeaderProps = commonComponentProps.extend({
  pinCount: z.number(),
  ...

A count of physical pins is inherently a positive integer, but nothing says so. The repo already uses the right idiom elsewhere — lib/components/analogacsweepsimulation.ts has z.number().int().positive() for sampleCount and samplesPerInterval.

Expected

pinCount should be a positive integer, rejected at parse time with a message naming the prop, rather than producing a mismatched component or surfacing later as an unrelated footprint error.

Valid counts must keep parsing to the same value — this shouldn't change behaviour for any real header.

PR follows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions