Empty string in `connections` crashes the render with a raw css-what parser error
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 58
- Forks
- 203
- Avg merge
- 7h 39m
- Merged PRs (30d)
- 286
Description
Summary
An empty string in connections aborts the whole render with a raw CSS-parser error that names neither the component nor the pin.
<board width="30mm" height="20mm" routingDisabled>
<resistor name="R1" resistance="1k" footprint="0402" pcbX={-8} />
<capacitor
name="C1"
capacitance="1uF"
footprint="0402"
connections={{ pin1: "", pin2: ".R1 > .pin1" }}
/>
</board>
Actual — renderUntilSettled() throws, and no circuit JSON is produced at all:
error: Expected name, found .
at getName (node_modules/css-what/lib/commonjs/parse.js:95:23)
at parseSelector (node_modules/css-what/lib/commonjs/parse.js:220:17)
at selectOne (lib/components/base-components/PrimitiveComponent/PrimitiveComponent.ts:1253:18)
at resolveImplicitSinglePort (lib/components/primitive-components/Trace/Trace__findConnectedPorts.ts:29:47)
Two separate problems:
- The message is not actionable.
Expected name, found .iscss-whatinternals. It doesn't say which component, which pin, or that the value was empty. Reading it, the natural guess is that.R1 > .pin1— the one target that is actually fine — is malformed. - It takes the whole board down. This is a thrown exception, not a recorded error, so the sibling valid connection, the other components, and every downstream phase never run. One typo in one prop produces zero output.
Cause
NormalComponent._createTracesFromConnectionsProp() forwards every entry of props.connections straight into a Trace's to:
for (const [pinName, target] of Object.entries(props.connections)) {
const targets = Array.isArray(target) ? target : [target]
for (const targetPath of targets) {
this.add(new Trace({ from: `.${this.name} > .${pinName}`, to: targetPath }))
}
}
An empty string isn't a selector, but nothing rejects it here, so to: "" reaches selectOne and css-what throws while parsing. The parser error surfaces from a call stack several layers below the prop the user actually wrote.
Note the value survives validation upstream too — connections is typed as a record of selector strings, and "" is a string, so the props schema accepts it.
Expected
An empty or whitespace-only target should be reported as a misconfiguration that names the component and the pin, and the rest of the board should still render — matching how other bad-input cases in the codebase behave (source_component_misconfigured_error, source_ambiguous_port_reference), which record an error and continue rather than throwing.
Suggested behaviour:
<capacitor#13 name=".C1" /> has an empty connections target for pin "pin1".
Provide a selector such as ".R1 > .pin1" or "net.VCC", or remove the entry.
…with the sibling pin2: ".R1 > .pin1" connection still producing its source_trace.
Scope / judgement calls left open
- I only treat empty and whitespace-only targets as misconfigured. A non-empty but unresolvable selector (e.g.
".R9 > .pin1"where R9 doesn't exist) already has its own downstream handling, so I deliberately left that path untouched. - The check sits in
_createTracesFromConnectionsPropso it covers both the string and array forms of aconnectionsentry. - Rejecting
""at the props-schema level intscircuit/propswould catch it earlier, but that's a cross-repo change with a wider blast radius (it would turn today's runtime crash into a hard parse failure for anyone who currently passes""deliberately). I kept the fix in core; happy to follow up in props if maintainers prefer that.
PR follows.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lib/components/primitive-components/NormalComponent/NormalComponent.ts at _createTracesFromConnectionsProp, then read the Trace path through PrimitiveComponent.ts and Trace__findConnectedPorts.ts. Verify the empty and whitespace-only cases against the existing misconfiguration error behavior; done means rendering records a component-and-pin error, continues, and still produces the valid sibling source_trace.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100