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.
Summary
pinHeaderProps.pinCountis declared as a barez.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.pinCountsource_portsEvery 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:
pcb_missing_footprint_errorpoints at the footprint. The mistake was the pin count.At the schema level:
(
NaNis already rejected — zod'sz.number()excludes it but notInfinity.)Cause
lib/components/pin-header.ts: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.tshasz.number().int().positive()forsampleCountandsamplesPerInterval.Expected
pinCountshould 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.