Skip to content

fix: don't report derived connectivity findings when autorouting was skipped - #182

Open
seveibar wants to merge 1 commit into
mainfrom
fix/skip-derived-findings-when-autorouting-skipped
Open

fix: don't report derived connectivity findings when autorouting was skipped#182
seveibar wants to merge 1 commit into
mainfrom
fix/skip-derived-findings-when-autorouting-skipped

Conversation

@seveibar

@seveibar seveibar commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Problem

Core skips autorouting for an entire subcircuit when it has placement errors, inserting

pcb_autorouting_error  pcb_autorouting_skipped_placement_errors_<subcircuit_id>
  "Autorouting was skipped because N PCB placement errors were found. ..."

Every source trace in that subcircuit then has no pcb_trace, so checkSourceTracesHavePcbTraces and checkEachPcbPortConnectedToPcbTraces each emit one finding per net. On a real board that means hundreds of pcb_trace_missing_error / pcb_port_not_connected_error entries pointing at nets that have nothing wrong with them, burying the one placement error that actually caused it.

Minimal shape of the confusion — a board with a single component sitting outside the outline and one unrelated, perfectly routable trace:

pcb_component_outside_board_error: Component R3 extends outside board boundaries...
pcb_autorouting_error:             Autorouting was skipped because 1 PCB placement error was found...
pcb_port_not_connected_error:      Ports [R1.pin2, R2.pin1] are not connected together through the same net.
pcb_trace_missing_error:           Trace [.R1 > .pin2 to .R2 > .pin1] is not connected (it has no PCB trace)

The last two describe R1/R2, which are fine. The router simply never ran.

Fix

Skip those two checks for source traces belonging to a subcircuit whose autorouting was skipped this way.

Deliberately narrow, because suppressing findings is easy to get wrong:

  • keyed to the pcb_autorouting_skipped_placement_errors_ error id, not to autorouting errors generally — a router that ran and failed (cF ran out of iterations) still reports everything
  • matched per subcircuit_id, so a skipped subcircuit never silences its siblings

Only the two checks that are pure consequences of "no traces exist" are touched; overlap, clearance and length checks are unaffected.

Tests

tests/lib/skipped-autorouting-suppresses-derived-errors.test.ts covers the behaviour and both guardrails:

  • findings still reported when autorouting ran
  • findings suppressed for the skipped subcircuit
  • not suppressed for a different subcircuit
  • not suppressed for an unrelated autorouting error

Full suite: 145 pass.

Related

🤖 Generated with Claude Code

…skipped

When core skips autorouting for a subcircuit because of placement errors, every
source trace in it lacks a pcb_trace. The connectivity checks then reported one
"not connected" / "missing pcb trace" finding per net, burying the single
placement error that actually caused it.

Scoped to the pcb_autorouting_skipped_placement_errors_* error id and matched
per subcircuit_id, so ordinary routing failures still report normally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment on lines +45 to +86
test("reports missing traces when autorouting actually ran", async () => {
const findings = await runAllRoutingChecks(circuitJson)
const types = findings.map((f) => f.type)
expect(types).toContain("pcb_trace_missing_error")
expect(types).toContain("pcb_port_not_connected_error")
})

test("suppresses derived findings when autorouting was skipped for placement errors", async () => {
const findings = await runAllRoutingChecks([
...circuitJson,
skippedAutoroutingError,
])
const types = findings.map((f) => f.type)
expect(types).not.toContain("pcb_trace_missing_error")
expect(types).not.toContain("pcb_port_not_connected_error")
})

test("does not suppress findings for other subcircuits", async () => {
const findings = await runAllRoutingChecks([
...circuitJson,
{
...(skippedAutoroutingError as any),
pcb_error_id: "pcb_autorouting_skipped_placement_errors_subcircuit_9",
subcircuit_id: "subcircuit_9",
} as unknown as AnyCircuitElement,
])
expect(findings.map((f) => f.type)).toContain("pcb_trace_missing_error")
})

test("does not suppress findings for unrelated autorouting errors", async () => {
const findings = await runAllRoutingChecks([
...circuitJson,
{
type: "pcb_autorouting_error",
pcb_error_id: "pcb_autorouting_error_0",
error_type: "pcb_autorouting_error",
subcircuit_id: "subcircuit_0",
message: "cF ran out of iterations",
} as unknown as AnyCircuitElement,
])
expect(findings.map((f) => f.type)).toContain("pcb_trace_missing_error")
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains 4 test(...) calls, but the style guide requires that a *.test.ts file may have AT MOST one test(...). Please split this into multiple numbered files, e.g. skipped-autorouting-suppresses-derived-errors1.test.ts, skipped-autorouting-suppresses-derived-errors2.test.ts, skipped-autorouting-suppresses-derived-errors3.test.ts, and skipped-autorouting-suppresses-derived-errors4.test.ts, each containing exactly one test(...) call.

Spotted by Graphite (based on custom rule: Custom rule)

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant