mastra-ai/mastra · error · HTTPException
outputStream phase cannot be executed directly. Use streamin
Error message
outputStream phase cannot be executed directly. Use streaming instead.
What it means
The outputStream phase is driven by streaming chunks during agent runs and has no request/response 'execute' form. The handler intentionally refuses direct execution of phase='outputStream' with HTTP 400, telling the caller to use the streaming endpoint instead.
Source
Thrown at packages/server/src/server/handlers/processors.ts:470
case 'outputStep':
if (!processor.processOutputStep) {
throw new HTTPException(400, { message: 'Processor does not support outputStep phase' });
}
result = await processor.processOutputStep({
...baseContext,
systemMessages: [],
stepNumber: 0,
steps: [],
finishReason: 'stop',
toolCalls: [],
text: extractTextFromMessages(messages),
usage: { inputTokens: undefined, outputTokens: undefined, totalTokens: undefined },
});
break;
case 'outputStream':
// outputStream is for streaming chunks, not a simple execute
throw new HTTPException(400, {
message: 'outputStream phase cannot be executed directly. Use streaming instead.',
});
default:
throw new HTTPException(400, { message: `Unknown phase: ${phase}` });
}
// Process the result
let outputMessages = messages;
if (result) {
if (Array.isArray(result)) {
outputMessages = result;
} else if (result.get && result.get.all && typeof result.get.all.db === 'function') {
// It's a MessageList
outputMessages = result.get.all.db();
} else if (result.messages) {
outputMessages = result.messages;
}View on GitHub (pinned to 75dd419e61)
Solutions
- Use the streaming processor endpoint (or a streaming agent run) to exercise outputStream behavior.
- Test with 'output' or 'outputResult' phases for request/response validation.
- Remove 'outputStream' from any hardcoded phase list sent to the execute endpoint.
Example fix
// before executeProcessor(id, 'outputStream', ctx); // after streamProcessor(id, ctx); // consumes the SSE/streaming route, which drives processOutputStream
Defensive patterns
Strategy: validation
Validate before calling
const EXECUTABLE_PHASES = ['input','inputStep','output','outputResult','outputStep'] as const;
if (!EXECUTABLE_PHASES.includes(phase as any)) {
throw new Error(`${phase} must run via the streaming endpoint`);
} Try / catch
try {
await exec(id, phase, ctx);
} catch (e) {
if (e instanceof HTTPException && e.status === 400 && e.message.includes('streaming')) {
return streamExec(id, ctx); // switch to SSE/streaming transport
}
throw e;
} Prevention
- Exclude 'outputStream' and other streaming-only phases from execute-endpoint callers.
- Use a streaming client to test processOutputStream behavior.
- Keep phase enums in one shared constant used by both client and server.
When it happens
Trigger: POSTing phase='outputStream' to the non-streaming processor execute endpoint in packages/server/src/server/handlers/processors.ts.
Common situations: Scripted phase enumeration including 'outputStream'; copying a streaming test to the plain execute endpoint; misunderstanding that outputStream is a chunk-callback hook, not an invokable transformation.
Related errors
- Stream part blocked by ${processor.id}
- ${tripwireChunk.payload?.reason || 'Agent tripwire triggered
- Processor does not support input phase
- Processor does not support inputStep phase
- Processor does not support outputResult phase
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d458e1dd38b071e4.
Report an issue: GitHub.