Skip to content

fix(solver): prevent infinite loop in solveUntilPhase after terminal state (#267) - #269

Open
PINYOPATTANAWASANPORN wants to merge 1 commit into
tscircuit:mainfrom
PINYOPATTANAWASANPORN:fix/solve-until-phase-terminal-state-loop-267
Open

PINYOPATTANAWASANPORN wants to merge 1 commit into
tscircuit:mainfrom
PINYOPATTANAWASANPORN:fix/solve-until-phase-terminal-state-loop-267

Conversation

@PINYOPATTANAWASANPORN

Copy link
Copy Markdown

Summary of Changes

  • Adds terminal-state guards (!this.solved && !this.failed) to LayoutPipelineSolver.solveUntilPhase(), aligning its loop invariants with BaseSolver.solve().
  • Adds regression unit test suite in tests/LayoutPipelineSolver/solveUntilPhaseTerminal.test.ts verifying termination behavior when the solver is already solved, failed, or reaches terminal state under unknown targets.

Root Cause / Technical Context

Fixes #267. In LayoutPipelineSolver.solveUntilPhase(phase: string), the loop condition previously evaluated only this.getCurrentPhase() !== phase.
Because BaseSolver.step() early-returns immediately once this.solved or this.failed is true:

  1. If an active child solver failed or the iteration budget was exhausted before reaching the requested phase, this.step() becomes a no-op.
  2. The outer while loop in solveUntilPhase() would never exit, causing an infinite loop that locks the execution runtime/event loop.

By adding !this.solved && !this.failed:

solveUntilPhase(phase: string) {
  while (!this.solved && !this.failed && this.getCurrentPhase() !== phase) {
    this.step()
  }
}

the solver halts cleanly when a terminal state is reached.

Verification & Testing

  • Validated termination against pre-failed states, pre-solved states, and unknown future targets.
  • All existing pipeline invariants and return types remain strictly intact.

…state (tscircuit#267)

Guards solveUntilPhase with !this.solved && !this.failed so that when the
solver has failed or solved before reaching the requested phase, execution
terminates immediately instead of repeatedly calling step() in a busy loop.
@vercel

vercel Bot commented Sep 18, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
matchpack Ready Ready Preview Sep 18, 2026 10:29am UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview d30c8231 Deployed Sep 18, 2026 by vercel[bot]
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.

solveUntilPhase can loop indefinitely after failure or completion

1 participant