can1357/oh-my-pi · error · Error

No active debug session. Launch or attach first.

Error message

No active debug session. Launch or attach first.

What it means

DapSessionManager.#getActiveSessionOrThrow guards every public operation that requires a live debug session. It throws when there is no session at all, or the current session is not in 'stopped' status with a live client. In short: you asked the debugger to do something while no debugger was running.

Source

Thrown at packages/coding-agent/src/dap/session.ts:1784

			return null;
		}
		const session = this.#sessions.get(this.#activeSessionId) ?? null;
		if (!session) {
			this.#activeSessionId = null;
		}
		return session;
	}

	/** True when the current active session is live and paused at a stop. */
	#hasLiveStoppedActiveSession(): boolean {
		const active = this.#getActiveSessionOrNull();
		return active !== null && active.status === "stopped" && active.client.isAlive();
	}

	#getActiveSessionOrThrow(): DapSession {
		const session = this.#getActiveSessionOrNull();
		if (!session) {
			throw new Error("No active debug session. Launch or attach first.");
		}
		return session;
	}

	#getRootSession(session: DapSession): DapSession {
		let root = session;
		while (root.parentSessionId) {
			const parent = this.#sessions.get(root.parentSessionId);
			if (!parent) break;
			root = parent;
		}
		return root;
	}

	#getTreeSessions(session: DapSession): DapSession[] {
		const sessions: DapSession[] = [];
		const pending = [this.#getRootSession(session)];
		while (pending.length > 0) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Launch or attach a debug session before issuing commands
  2. Check session status (e.g. a status/isAlive accessor) before calling operations, and surface 'start a debug session first' guidance to the user
  3. Handle the case where the debuggee terminated normally — treat subsequent commands as no-ops
  4. If a session unexpectedly disappeared, re-launch/attach it

Example fix

// before
await sessionManager.setBreakpoint('/a.ts', 10); // throws: no active session
// after
if (await sessionManager.hasActiveSession()) {
	await sessionManager.setBreakpoint('/a.ts', 10);
} else {
	await sessionManager.launch({ type: 'node', program: '/a.js' });
}
Defensive patterns

Strategy: validation

Validate before calling

const active = manager.getActiveSession?.();
if (!active || active.status !== 'stopped' || !active.client?.isAlive?.()) {
	throw new SkipOperation('no active debug session');
}

Type guard

function hasActiveSession(s) { return s !== null && s.status === 'stopped' && s.client.isAlive(); }

Try / catch

try {
	await manager.setBreakpoint(file, line);
} catch (err) {
	if (err.message.includes('No active debug session')) {
		await manager.launch(config); // start session then retry
	}
}

Prevention

When it happens

Trigger: Calling methods like setBreakpoint, stackTrace, evaluate, continue, or step on a DapSessionManager instance before calling launch/attach, or after the session was terminated/disposed.

Common situations: Running debug commands from an automation/agent tool without first launching the debugger; the debuggee exited and the session was cleaned up; attaching failed earlier and the error was swallowed; managing multiple sessions and the active one was closed.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/36a9aa0339b65612. Report an issue: GitHub.