stablyai/orca · warning
startup_terminal_missing
startup_terminal_missing
Error message
startup_terminal_missing
What it means
Thrown when a worktree's setup script is configured to launch in a split pane (setupScriptLaunchMode = 'split-vertical' | 'split-horizontal') but no startup terminal handle exists to split from. The split operation needs a parent terminal; the handle is captured when the startup terminal is created. If that terminal was never created (e.g. no startup command was produced for this worktree), the handle is null and the split is impossible. The throw is a guard so splitTerminal never receives undefined.
Source
Thrown at src/main/ipc/worktree-remote.ts:352
let didSpawnSetup = false
if (setup) {
try {
const setupCommand =
wrappedSetupCommandStr ??
buildSetupRunnerCommand(
setup.runnerScriptPath,
getSetupRunnerCommandPlatformForLaunch(
setup,
process.platform === 'win32' ? 'windows' : 'posix'
),
setup.shell
)
const setupLaunchMode =
(settings as Partial<Pick<GlobalSettings, 'setupScriptLaunchMode'>>)
.setupScriptLaunchMode ?? 'new-tab'
if (setupLaunchMode === 'split-vertical' || setupLaunchMode === 'split-horizontal') {
if (!startupTerminalHandle) {
throw new Error('startup_terminal_missing')
}
await runtime.splitTerminal(startupTerminalHandle, {
direction: setupLaunchMode === 'split-horizontal' ? 'horizontal' : 'vertical',
command: setupCommand,
env: setup.envVars,
activate: false
})
} else {
await runtime.createTerminal(`id:${worktree.id}`, {
title: 'Setup',
command: setupCommand,
env: setup.envVars,
activate: false
})
}
didSpawnSetup = true
} catch (error) {
const message = error instanceof Error ? error.message : String(error)View on GitHub (pinned to 1136503c6a)
Solutions
- Set setupScriptLaunchMode back to 'new-tab' in Settings so the setup script gets its own terminal instead of splitting a nonexistent one.
- Ensure the repo/worktree has a real startup command so a startup terminal is created (the handle is captured at line 322).
- If splitting is required, verify the startup terminal actually spawned before the setup block runs; treat a missing handle as a degraded 'new-tab' fallback rather than throwing.
Example fix
// before
if (!startupTerminalHandle) {
throw new Error('startup_terminal_missing')
}
await runtime.splitTerminal(startupTerminalHandle, { ... })
// after — degrade to a new tab when no terminal exists to split
if (!startupTerminalHandle) {
await runtime.createTerminal(`id:${worktree.id}`, { title: 'Setup', command: setupCommand, env: setup.envVars, activate: false })
} else {
await runtime.splitTerminal(startupTerminalHandle, { ... })
} Defensive patterns
Strategy: validation
Validate before calling
// Before create: ensure split mode has a startup terminal to split from
const mode = settings.setupScriptLaunchMode ?? 'new-tab'
const isSplit = mode === 'split-vertical' || mode === 'split-horizontal'
if (isSplit && !hasStartupCommandForWorktree(repo, worktree)) {
// downgrade instead of letting the main process throw
effectiveMode = 'new-tab'
} Type guard
function canSplitSetup(
mode: string | undefined,
startupTerminalHandle: string | null
): startupTerminalHandle is string {
return (mode === 'split-vertical' || mode === 'split-horizontal') && startupTerminalHandle !== null
} Try / catch
// In the setup spawn block, treat a missing handle as degraded new-tab
catch (err) {
if (err instanceof Error && err.message === 'startup_terminal_missing') {
await runtime.createTerminal(`id:${worktree.id}`, { title: 'Setup', command: setupCommand, env: setup.envVars, activate: false })
didSpawnSetup = true
} else { throw err }
} Prevention
- Only offer split modes in the UI when a startup command is configured for the repo.
- Treat a missing startup terminal as a soft degradation (new-tab), not a hard failure.
- Surface the warning captured at lines 327-332 to the user so they know the startup terminal failed.
When it happens
Trigger: A create/open flow that produces a setup script but no sequenced startup terminal (startup command empty or skipped), while GlobalSettings.setupScriptLaunchMode is set to split-vertical or split-horizontal. Reached inside spawnSetupForRemoteWorktreeCreate / the launch path at worktree-remote.ts:350-353.
Common situations: Repo hooks define a setup script but no startup command; user switched setupScriptLaunchMode to a split mode in Settings; agent/TUI launch path that bypasses the startup terminal; a partial state where the startup terminal creation earlier returned a warning (lines 327-332) but execution continued into the setup block.
Related errors
- Timed out polling ${label} after ${pollTimeoutMs}ms.
- Timed out waiting for ${label}; last value: ${JSON.stringify
- No active terminal pane to focus.
- No active terminal pane for scrollback API scroll.
- Need ≥2 terminals to bulk-switch; got ${switchTargets.length
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/8b377163343c835f.
Report an issue: GitHub.