mastra-ai/mastra · error · HTTPException
Unknown phase: ${phase}
Error message
Unknown phase: ${phase} What it means
The phase switch has cases for input, inputStep, output, outputResult, outputStep and outputStream; anything else falls to the default branch which throws HTTP 400 'Unknown phase: <phase>'. This guards against typo'd or unsupported phase identifiers from the client.
Source
Thrown at packages/server/src/server/handlers/processors.ts:475
...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;
}
}
return {
success: true,
phase,View on GitHub (pinned to 75dd419e61)
Solutions
- Use an exact, lowercase phase name: input, inputStep, output, outputResult, or outputStep.
- Check the API route schema/OpenAPI spec for the enumerated phase values.
- Update the client SDK or playground version so phase names match the server.
Example fix
// before
body: JSON.stringify({ phase: 'Output', messages })
// after
body: JSON.stringify({ phase: 'output', messages }) Defensive patterns
Strategy: validation
Validate before calling
const VALID_PHASES = ['input','inputStep','output','outputResult','outputStep','outputStream'];
if (!VALID_PHASES.includes(phase)) {
throw new Error(`Unknown phase "${phase}"; expected one of ${VALID_PHASES.join(', ')}`);
} Type guard
type Phase = 'input' | 'inputStep' | 'output' | 'outputResult' | 'outputStep' | 'outputStream';
function isPhase(v: string): v is Phase {
return ['input','inputStep','output','outputResult','outputStep','outputStream'].includes(v);
} Try / catch
try {
await exec(id, phase, ctx);
} catch (e) {
if (e instanceof HTTPException && e.status === 400 && e.message.startsWith('Unknown phase')) {
console.error(`Bad phase: ${e.message}. Valid: input, inputStep, output, outputResult, outputStep`);
return;
}
throw e;
} Prevention
- Use the typed Phase union from the SDK instead of raw strings.
- Validate request bodies with the route's zod/OpenAPI schema client-side.
- Watch for casing: phases are all-lowercase camelCase tokens.
When it happens
Trigger: Sending a phase value not in the handler's switch (e.g. 'Input', 'pre-process', 'transform', or an empty string) to the processor execute endpoint.
Common situations: Typos or wrong casing in API calls; older client versions sending renamed phases; hand-rolled scripts guessing phase names.
Understand the failure class
Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.
Related errors
- Processor does not support input phase
- Processor does not support inputStep phase
- Processor does not support outputResult phase
- Processor does not support outputStep phase
- outputStream phase cannot be executed directly. Use streamin
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/ea77c1ee41770f13.
Report an issue: GitHub.