can1357/oh-my-pi · error
Cannot continue: no messages in context
Error message
Cannot continue: no messages in context
What it means
agentLoopContinue continues an existing conversation by re-entering the agent loop with the context's message history. If context.messages is empty there is nothing to continue from, so it throws immediately (synchronously from the EventStream factory). This is a programmer/usage error: continue was called on a fresh or reset context instead of after at least one message.
Source
Thrown at packages/agent/src/agent-loop.ts:595
/**
* Continue an agent loop from the current context without adding a new message.
* Used for retries - context already has user message or tool results.
*
* **Important:** The last message in context must convert to a `user` or `toolResult` message
* via `convertToLlm` — except for an assistant tail with unpaired runnable
* tool calls (see {@link unpairedToolCallTail}), which resumes by executing
* those calls first. Any other assistant tail is rejected here; other invalid
* tails cannot be validated since `convertToLlm` is only called once per turn.
*/
export function agentLoopContinue(
context: AgentContext,
config: AgentLoopConfig,
signal?: AbortSignal,
streamFn?: StreamFn,
): EventStream<AgentEvent, AgentMessage[]> {
if (context.messages.length === 0) {
throw new Error("Cannot continue: no messages in context");
}
if (context.messages[context.messages.length - 1].role === "assistant" && !unpairedToolCallTail(context.messages)) {
throw new Error("Cannot continue from message role: assistant");
}
const stream = createAgentStream();
(async () => {
const newMessages: AgentMessage[] = [];
const currentContext: AgentContext = { ...context, messages: [...context.messages] };
stream.push({ type: "agent_start" });
try {
await runLoop(currentContext, newMessages, config, signal, stream, streamFn);
} catch (err) {
stream.fail(err);View on GitHub (pinned to 9690622007)
Solutions
- Use the initial-prompt entrypoint (agentLoop / prompt) instead of continue when the context has no messages.
- Restore the message history before continuing (reload session state into context.messages).
- Guard the call site: only invoke continue when context.messages.length > 0.
Example fix
// before
await agentLoopContinue(context, config);
// after
if (context.messages.length === 0) {
await agentLoop(context, [userMessage], config);
} else {
await agentLoopContinue(context, config);
} Defensive patterns
Strategy: validation
Validate before calling
if (context.messages.length === 0) {
return agentLoop(context, [initialUserMessage], config);
}
return agentLoopContinue(context, config); Type guard
function canContinue(context: AgentContext): boolean {
return context.messages.length > 0;
} Try / catch
try {
return agentLoopContinue(context, config);
} catch (err) {
if (err instanceof Error && err.message.includes("no messages in context")) {
return agentLoop(context, [initialUserMessage], config);
}
throw err;
} Prevention
- Only call continue on contexts restored from a saved session or after a completed turn.
- Verify session load actually populated messages before resuming.
- Route fresh contexts to the prompt/initial-loop entrypoint.
When it happens
Trigger: Calling agentLoopContinue(context, config) (via stream) with a brand-new AgentContext, a context that was cleared, or before any user message was pushed.
Common situations: Resuming a session file that failed to load (messages never restored); calling continue on a newly constructed agent instead of prompt/first turn; error-recovery paths that retry continue after the context was rebuilt empty.
Related errors
- Cannot continue from message role: assistant
- too many templates
- extra operand {} file operands cannot be combined with --fil
- multiple output files specified
- when reading file names from standard input, no file name of
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/058b8a4ba78bb996.
Report an issue: GitHub.