can1357/oh-my-pi · error · Error
No active stack frame. Run stack_trace first or supply frame
Error message
No active stack frame. Run stack_trace first or supply frame_id.
What it means
DapSessionManager.scopes needs a stack frame id to request variable scopes from the adapter. It resolves frameId from the argument or from the session's last recorded stop (set by stack_trace). If neither exists — the session never stopped or stack_trace was never run — there is no frame to query, so it throws.
Source
Thrown at packages/coding-agent/src/dap/session.ts:1067
...(frameCount !== undefined ? { levels: frameCount } : {}),
} satisfies DapStackTraceArguments,
signal,
timeoutMs,
);
session.lastStackFrames = response?.stackFrames ?? [];
this.#applyTopFrame(session, session.lastStackFrames[0]);
return {
snapshot: buildSummary(session),
stackFrames: session.lastStackFrames,
totalFrames: response?.totalFrames,
};
}
async scopes(frameId: number | undefined, signal?: AbortSignal, timeoutMs: number = 30_000) {
const session = this.#touchActiveSession();
const resolvedFrameId = frameId ?? session.stop.frameId;
if (resolvedFrameId === undefined) {
throw new Error("No active stack frame. Run stack_trace first or supply frame_id.");
}
const response = await this.#sendRequestWithConfig<DapScopesResponse>(
session,
"scopes",
{ frameId: resolvedFrameId } satisfies DapScopesArguments,
signal,
timeoutMs,
);
return { snapshot: buildSummary(session), scopes: response?.scopes ?? [] };
}
async variables(variableReference: number, signal?: AbortSignal, timeoutMs: number = 30_000) {
const session = this.#touchActiveSession();
const response = await this.#sendRequestWithConfig<DapVariablesResponse>(
session,
"variables",
{ variablesReference: variableReference } satisfies DapVariablesArguments,
signal,View on GitHub (pinned to 9690622007)
Solutions
- Run the stack_trace tool/request first so the session records a stop frame, then call scopes()
- Pass an explicit numeric frameId obtained from a previous stack_trace response
- Only call scopes() while the debuggee is stopped (after a stopped event); check session status first
- If the program resumed, break again before querying scopes
Example fix
// before
const scopes = await manager.scopes(undefined); // no stop recorded
// after
const trace = await manager.stackTrace(undefined);
const frameId = trace.stackFrames[0]?.id;
if (frameId === undefined) throw new Error('debuggee not stopped');
const scopes = await manager.scopes(frameId); Defensive patterns
Strategy: validation
Validate before calling
const active = session.status === 'stopped' ? session.stop?.frameId : undefined;
if (active === undefined) {
await manager.stackTrace(); // record the stop frame first
} Type guard
function hasActiveFrame(session: DapSession): session is DapSession & { stop: { frameId: number } } {
return typeof session.stop?.frameId === 'number';
} Try / catch
try {
return await manager.scopes(frameId);
} catch (err) {
if (String((err as Error).message).includes('No active stack frame')) {
await manager.stackTrace();
return await manager.scopes(undefined); // retry with recorded frame
}
throw err;
} Prevention
- Always run stack_trace immediately after a stopped event before scopes/variables
- Only call scopes while the debuggee is paused; resume invalidates frame ids
- Pass explicit frameId from prior stack_trace output rather than relying on session state
- Check session status before variable queries in tool flows
When it happens
Trigger: Calling scopes() on a session that has not hit a breakpoint/stop and without a frameId argument; calling scopes() after the stop state was cleared (resumed/terminated); passing frameId: undefined explicitly while no stack trace was captured.
Common situations: Tool flow calls scopes before running stack_trace; evaluating scopes after the program resumed so stop.frameId was invalidated; session attached but program running (no stop events yet); new session created without any stop recorded.
Related errors
- DAP adapter ${this.adapter.name} is not running
- DAP adapter ${this.adapter.name} exited before write complet
- Adapter process exited before socket was ready
- Socket not ready after ${timeoutMs}ms
- directory stack is empty
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bd347d043bbe138f.
Report an issue: GitHub.