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
- Rebuild the studio to regenerate a correct routes-manifest.json.
- Open routes-manifest.json and confirm it is an array of strings like ["api","agents"].
- Check for a deployer/studio version mismatch and upgrade the deployer.
- 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
- Keep deployer and studio package versions in sync.
- Rebuild the studio after any upgrade so the manifest shape matches.
- Don't hand-edit routes-manifest.json.
- Validate the manifest shape once at build time in CI.
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
- Failed to read studio routes manifest at "${manifestPath}":
- Failed to copy studio assets from "${studioSource}" to "${st
- ${PLUGIN_MANIFEST_FILE} must contain a plugins array
- ${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an
- App creation failed: ${errorDetails}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/305880ee33fb1418.
Report an issue: GitHub.