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

  1. Use an exact, lowercase phase name: input, inputStep, output, outputResult, or outputStep.
  2. Check the API route schema/OpenAPI spec for the enumerated phase values.
  3. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/ea77c1ee41770f13. Report an issue: GitHub.