mastra-ai/mastra · info · HTTPException

Phase is required

Error message

Phase is required

What it means

POST /processors/:processorId/execute throws this HTTP 400 when the request body omits the `phase` field. The execute endpoint needs to know which processor phase (`input`, `inputStep`, `outputResult`, `outputStep`, etc.) to run.

Source

Thrown at packages/server/src/server/handlers/processors.ts:213

  path: '/processors/:processorId/execute',
  responseType: 'json',
  pathParamSchema: processorIdPathParams,
  bodySchema: executeProcessorBodySchema,
  responseSchema: executeProcessorResponseSchema,
  summary: 'Execute processor',
  description: 'Executes a specific processor with the provided input data',
  tags: ['Processors'],
  requiresAuth: true,
  handler: async ({ mastra, processorId, ...bodyParams }) => {
    try {
      const { phase, messages } = bodyParams;

      if (!processorId) {
        throw new HTTPException(400, { message: 'Processor ID is required' });
      }

      if (!phase) {
        throw new HTTPException(400, { message: 'Phase is required' });
      }

      if (!messages || !Array.isArray(messages)) {
        throw new HTTPException(400, { message: 'Messages array is required' });
      }

      // Get the processor from Mastra's registered processors
      let processor;
      try {
        processor = mastra.getProcessorById(processorId);
      } catch {
        // getProcessorById throws if not found, try by key
        const processors = mastra.listProcessors() || {};
        processor = processors[processorId as keyof typeof processors];
      }

      if (!processor) {
        throw new HTTPException(404, { message: 'Processor not found' });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Add `phase` to the JSON body, e.g. `"phase": "input"`.
  2. Use a phase the processor actually implements (check GET /processors/:id for its `phases` list).
  3. Note that `outputStream` is rejected separately — for streaming phases use the streaming path instead.

Example fix

// before
await fetch(url, { method: 'POST', body: JSON.stringify({ messages }) });
// after
await fetch(url, { method: 'POST', body: JSON.stringify({ phase: 'input', messages }) });
Defensive patterns

Strategy: validation

Validate before calling

const VALID_PHASES = ['input', 'inputStep', 'outputResult', 'outputStep'];
if (!VALID_PHASES.includes(phase)) {
  throw new Error(`phase must be one of ${VALID_PHASES.join(', ')} before executing a processor`);
}

Type guard

type ProcessorPhase = 'input' | 'inputStep' | 'outputResult' | 'outputStep';
function isValidPhase(p: unknown): p is ProcessorPhase {
  return typeof p === 'string' && ['input', 'inputStep', 'outputResult', 'outputStep'].includes(p);
}

Try / catch

try {
  const res = await fetch(url, { method: 'POST', body: JSON.stringify({ phase, messages }) });
  if (res.status === 400 && (await res.json()).message === 'Phase is required') {
    throw new Error('Client bug: phase omitted from execute body');
  }
  return await res.json();
} catch (e) {
  console.error(e);
  throw e;
}

Prevention

When it happens

Trigger: POST /processors/:id/execute with a body like `{ messages: [...] }` but no `phase` key, or `phase: undefined` from an unset variable in client code.

Common situations: Copy-pasting an execute call from another endpoint that has no phase concept; client SDK version mismatch where phase moved into a nested object; forgetting phase when testing the endpoint with curl/Postman.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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