mastra-ai/mastra · error

expected an array of route segments

Error message

expected an array of route segments

What it means

readStudioRouteRoots parses studio's routes-manifest.json and requires it to be a JSON array of strings (route segments). If the parsed value is not an array or contains non-string entries, this sentinel error is thrown, then immediately re-wrapped by the catch block as 'Failed to read studio routes manifest...'.

Source

Thrown at deployers/vercel/src/index.ts:83

        );
      }

      this.injectStudioConfig(staticDir);
    }
  }

  /**
   * Studio's top-level route segments, emitted by the Studio build alongside index.html.
   * The Vercel route table needs them explicitly: custom `registerApiRoute()` paths are mounted
   * at the root of the server, so the function has to own every path Studio doesn't claim.
   */
  private readStudioRouteRoots(studioSource: string): string[] {
    const manifestPath = join(studioSource, 'routes-manifest.json');

    try {
      const roots = JSON.parse(readFileSync(manifestPath, 'utf-8'));
      if (!Array.isArray(roots) || roots.some(root => typeof root !== 'string')) {
        throw new Error('expected an array of route segments');
      }
      return roots;
    } catch (err) {
      throw new Error(
        `Failed to read studio routes manifest at "${manifestPath}": ${err instanceof Error ? err.message : err}`,
      );
    }
  }

  private getEntry(): string {
    return `
import { handle } from 'hono/vercel'
import { mastra } from '#mastra';
import { createHonoServer, getToolExports } from '#server';
import { tools } from '#tools';
import { scoreTracesWorkflow } from '@mastra/core/evals/scoreTraces';

if (mastra.getStorage()) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Rebuild the studio to regenerate a correct routes-manifest.json.
  2. Open routes-manifest.json and confirm it is an array of strings like ["api","agents"].
  3. Check for a deployer/studio version mismatch and upgrade the deployer.
  4. Delete the manifest and rerun the studio build to rule out stale output.

Example fix

// before (routes-manifest.json)
{ "routes": ["api"] }
// after
["api", "agents"]
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync } from 'node:fs';
const manifest = JSON.parse(readFileSync(join(studioSource, 'routes-manifest.json'), 'utf-8'));
const isValid = Array.isArray(manifest) && manifest.every(r => typeof r === 'string');
if (!isValid) throw new Error('routes-manifest.json must be an array of strings');

Type guard

function isRouteRoots(value: unknown): value is string[] {
  return Array.isArray(value) && value.every((r): r is string => typeof r === 'string');
}

Try / catch

try {
  await deployer.prepare();
} catch (err) {
  if (String((err as Error).message).includes('routes manifest')) {
    console.error('Manifest missing or malformed — rebuild the studio:', (err as Error).message);
  }
  throw err;
}

Prevention

When it happens

Trigger: routes-manifest.json contains an object, a string, or an array of numbers/objects instead of an array of strings; produced by a studio build with an incompatible or corrupted manifest format.

Common situations: Version mismatch between the deployer and the studio build outputting a new manifest shape; a hand-edited or truncated manifest file; a stale manifest from a previous build.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — 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/305880ee33fb1418. Report an issue: GitHub.