stablyai/orca · error · Error
Need ≥2 terminals to bulk-switch; got ${switchTargets.length
Error message
Need ≥2 terminals to bulk-switch; got ${switchTargets.length}. notes=${notes.join('; ')} What it means
The bulk-switch phase requires at least two distinct terminal handles to exercise cross-terminal switching under load. The script unions newly-created terminals with already-live ones, dedupes by handle, optionally caps the set, and then asserts >= 2 remain. With fewer than two, the switch amplification would be a degenerate no-op that cannot reproduce the freeze.
Source
Thrown at config/scripts/live-remote-bulk-open-freeze-repro.mjs:190
(t) => typeof t.handle === 'string' && t.handle.startsWith('term_') && t.connected !== false
)
.map((t) => ({ handle: t.handle, title: t.title, worktreeId: t.worktreeId }))
notes.push(`live terminals listed=${live.length}`)
} catch (error) {
notes.push(`terminal list failed: ${String(error).slice(0, 200)}`)
}
let switchTargets = [...created.map((c) => c.handle), ...live.map((t) => t.handle)].filter(
(v, i, a) => typeof v === 'string' && a.indexOf(v) === i
)
if (shouldCapSwitchTargets(maxSwitchTargets) && switchTargets.length > maxSwitchTargets) {
switchTargets = applySwitchTargetCap(switchTargets, maxSwitchTargets)
amplificationSteps.push(`capped switchTargets=${maxSwitchTargets}`)
}
if (switchTargets.length < 2) {
throw new Error(
`Need ≥2 terminals to bulk-switch; got ${switchTargets.length}. notes=${notes.join('; ')}`
)
}
amplificationSteps.push(
`switchTargets=${switchTargets.length} passes=${switchPasses} parallel=${parallel}`
)
console.log(
`[live-freeze] bulk-switching ${switchTargets.length} terminals × ${switchPasses} passes (parallel=${parallel})`
)
let maxSwitchMs = 0
let maxBatchWallMs = 0
let sumSwitchMs = 0
let switchCount = 0
const switchStarted = performance.now()
for (let pass = 0; pass < switchPasses; pass += 1) {View on GitHub (pinned to 1136503c6a)
Solutions
- Increase createCount so at least two terminals are guaranteed created, or open terminals manually first.
- Inspect the joined notes string in the message — it reports list failures and counts that pinpoint whether create or list is the lossy step.
- If applySwitchTargetCap is collapsing the set, raise maxSwitchTargets or disable the cap via shouldCapSwitchTargets.
- Verify the live terminal handle field name matches what listLiveTerminalHandles reads so dedup keeps the values.
Example fix
// before const createCount = 0 // after const createCount = Math.max(2, createCount)
Defensive patterns
Strategy: validation
Validate before calling
if (createCount + liveCount < 2) {
throw new Error(`Need >=2 terminals for bulk-switch; createCount=${createCount} live=${liveCount}`)
} Type guard
const hasMinHandles = (arr, n = 2) => Array.isArray(arr) && arr.filter(h => typeof h === 'string').length >= n
Prevention
- Compute the expected handle union size before launching the expensive switch phase.
- Log created.length and live.length into notes so a shortfall is diagnosable.
- Disable the switch-target cap when the source set is already small.
When it happens
Trigger: createCount is 0 or all create calls failed AND the live terminal list returned zero or one handle; or the cap (maxSwitchTargets) reduced the deduped set below 2; or handles came back as non-strings and were filtered out by the typeof v === 'string' guard.
Common situations: Running with createCount=0 against an idle environment with one open terminal, a remote where terminal creation silently failed, a version mismatch returning handles under a different field name so they all get filtered, or an overly aggressive maxSwitchTargets cap.
Related errors
- Need ≥2 terminals; got ${openTargets.length}. ${notes.join('
- invalid_argument
- Package version is not valid semver: ${baseVersion}
- Adhoc build timestamp is invalid.
- Adhoc label has no usable characters: ${JSON.stringify(label
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/c23f14d018a4eb39.
Report an issue: GitHub.