Skip to content

fix(schematic): resolve netlabel net connections to the net's ports (floating power net label)#2559

Open
chayan-1906 wants to merge 1 commit into
tscircuit:mainfrom
chayan-1906:fix/3759-floating-power-net-label
Open

fix(schematic): resolve netlabel net connections to the net's ports (floating power net label)#2559
chayan-1906 wants to merge 1 commit into
tscircuit:mainfrom
chayan-1906:fix/3759-floating-power-net-label

Conversation

@chayan-1906

Copy link
Copy Markdown

Fixes tscircuit/tscircuit.com#3759

Problem

A power net label connected through a net renders a phantom rail on top of an unrelated component:

<resistor name="R3" ... connections={{ pin1: "net.C", pin2: "net.CENTER" }} />
<netlabel net="V5" connection="net.C" />

The V5 rail correctly appears at R3.pin1, but a second, floating V5 rail is drawn on top of R1 (whichever component sits at schematic origin).

Root cause

NetLabel._getConnectedPorts() resolves the connection selector with selectOne(connection) and casts the result to Port. For a net selector like "net.C" this returns the Net instance, which has no schematic position, so the user's label anchors at the fallback (0, 0).

For power/ground nets the schematic trace solver then places its own rail at the real pin (getSchematicPortIdsWithAssignedNetLabels can't see that the pin already has a user-defined label, for the same reason), routes a stub trace to it, and marks the port connected — so insertNetLabelsForPortsMissingTrace never rescues the stranded user label. Result: a correct rail at R3.pin1 plus a floating duplicate at (0, 0).

Non-power labels were silently rescued by the missing-trace pass, which is why only power/ground rails visibly floated — though they still produced two identical labels stacked at the pin.

Fix

Resolve net selectors to the net's connected ports (Net.getAllConnectedPorts()) in _getConnectedPorts(). The user label then anchors at the real pin, and the existing solver logic skips both the duplicate placement (applyNetLabelPlacements) and the stub trace (applyTracesFromSolverOutput).

Before (issue repro): two V5 labels — (0.00, 0.00) on top of R1 + (-0.65, 4.36) near R3.
After: one V5 label at (-0.55, 3.96) = R3.pin1, rail_up symbol kept.
Regular labels (e.g. net="MYNET"): same position as before, no longer duplicated.

Testing

  • New repro test tests/repros/repro142-floating-power-net-label.test.tsx — fails on main (phantom anchors 3.99 units away from R3.pin1), passes with the fix
  • All netlabel tests pass (24 tests across 23 files)
  • Full suite: 1131 pass / 28 skip; the only failure (autorouter-preset-laser-prefab) also fails on unmodified main (pre-existing)
  • bunx tsc --noEmit clean, biome format clean, bun run build succeeds

🤖 Generated with Claude Code

A netlabel with a net selector connection (e.g. connection="net.C")
treated the resolved Net instance as a Port. A Net has no schematic
position, so the user's label anchored at (0,0) - on top of whatever
component sat there. For power/ground nets the schematic trace solver
then added its own rail at the real pin and marked the port connected,
so the stranded user label was never rescued, producing a floating
duplicate power rail (tscircuit/tscircuit.com#3759).

Resolve net selectors to the net's connected ports instead. The user
label now anchors at the real pin and the solver skips its duplicate
placement and stub trace.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tscircuit-core-benchmarks Ready Ready Preview, Comment Jul 2, 2026 4:27pm

Request Review

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has had no recent activity. It will be closed if no further activity occurs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Floating power net label

1 participant