can1357/oh-my-pi · error · Error
Debug session ${root.id} is still active. Terminate it befor
Error message
Debug session ${root.id} is still active. Terminate it before launching another. What it means
The manager enforces a single active debug session tree: before launching a new root session it disposes dead sessions, then checks for any surviving root session. If one exists, launching another is rejected so the single-session invariant holds and adapter resources are not duplicated.
Source
Thrown at packages/coding-agent/src/dap/session.ts:1331
session.dataBreakpoints = root.dataBreakpoints.map(entry => ({ ...entry }));
} catch (error) {
logger.debug("Failed to bind data breakpoints in child debug session", {
sessionId: session.id,
error: toErrorMessage(error),
});
}
}
}
async #ensureLaunchSlot(): Promise<void> {
for (const session of [...this.#sessions.values()]) {
if (session.status === "terminated" || !session.client.isAlive()) {
this.#disposeSession(session);
}
}
const root = [...this.#sessions.values()].find(session => !session.parentSessionId);
if (!root) return;
throw new Error(`Debug session ${root.id} is still active. Terminate it before launching another.`);
}
#registerSession(
client: DapClient,
adapter: DapResolvedAdapter,
cwd: string,
program?: string,
parentSessionId?: string,
): DapSession {
const session: DapSession = {
id: `debug-${++this.#nextId}`,
adapter,
cwd,
program,
client,
status: "launching",
launchedAt: Date.now(),
lastUsedAt: Date.now(),View on GitHub (pinned to 9690622007)
Solutions
- Terminate the existing root session first (terminate/disconnect tool or manager call), then launch
- If the adapter hung, force-dispose: check isAlive() and kill the adapter process / dispose the session
- Enumerate existing sessions and pick the active one instead of launching a duplicate
- Make launch flows idempotent: reuse the active session if the same program/config is requested
Example fix
// before
await manager.launch(config); // throws if a session is active
// after
const existing = manager.listSessions().find(s => !s.parentSessionId);
if (existing && existing.status !== 'terminated') {
await manager.terminate(existing.id);
}
await manager.launch(config); Defensive patterns
Strategy: try-catch
Validate before calling
const rootActive = manager.listSessions().some(s => !s.parentSessionId && s.status !== 'terminated'); if (rootActive) await manager.terminate(rootActive.id);
Try / catch
try {
await manager.launch(config);
} catch (err) {
if (String((err as Error).message).includes('is still active')) {
const root = manager.listSessions().find(s => !s.parentSessionId);
if (root) await manager.terminate(root.id);
await manager.launch(config);
} else { throw err; }
} Prevention
- Always terminate the previous debug session before launching a new one
- Make launch flows idempotent: reuse or restart the existing session instead of failing
- Force-dispose sessions whose adapter hung (client alive but debuggee stuck)
- Track session state in your tool/UI to disable launch while a session is active
When it happens
Trigger: Calling launch/attach for a new root session while a previous root session still exists with status not 'terminated' and a live client; a previous session's client is still alive (adapter process running) even though the user considers the run finished; attempting a second launch without terminate/disconnect of the first.
Common situations: User starts a new debug run without stopping the previous one; a hung adapter keeps the old session 'active' (client alive, debuggee stuck); scripts that call launch repeatedly without terminate between runs; a breakpoint hit and session paused while a new launch is attempted.
Related errors
- DAP adapter ${this.adapter.name} is not running
- Daemon ${spec.name} is already ${existing.snapshot.state}
- Collab replica activation was cancelled
- DAP adapter ${this.adapter.name} exited before write complet
- Adapter process exited before socket was ready
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/208d26e5296324a5.
Report an issue: GitHub.