mastra-ai/mastra · error

Failed to read studio routes manifest at "${manifestPath}":

Error message

Failed to read studio routes manifest at "${manifestPath}": ${err instanceof Error ? err.message : err}

What it means

This is the wrapper error thrown when reading or parsing studio's routes-manifest.json fails for any reason: the file doesn't exist (ENOENT), is invalid JSON, or fails the array-of-strings validation (error 272). The original cause is embedded in the message via err.message.

Source

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

    }
  }

  /**
   * 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()) {
  mastra.__registerInternalWorkflow(scoreTracesWorkflow);
}

const app = await createHonoServer(mastra, { tools: getToolExports(tools) });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Build the studio first so routes-manifest.json exists in studioSource.
  2. Check the embedded err.message for the root cause (ENOENT vs JSON parse vs shape).
  3. Verify your outputDirectory/studioSource configuration points at the built studio output.
  4. Clean the build cache and rebuild if the manifest appears truncated.

Example fix

// before
vercel deploy  # .vercel/output built without studio manifest
// after
pnpm build:studio && vercel deploy
Defensive patterns

Strategy: try-catch

Validate before calling

import { existsSync } from 'node:fs';
const manifestPath = join(studioSource, 'routes-manifest.json');
if (!existsSync(manifestPath)) {
  throw new Error(`Missing ${manifestPath}; run the studio build before deploying.`);
}

Try / catch

try {
  await deployer.prepare();
} catch (err) {
  const msg = (err as Error).message;
  if (msg.includes('Failed to read studio routes manifest')) {
    if (msg.includes('ENOENT')) console.error('Studio not built; build it first.');
    else console.error('Manifest unreadable/invalid:', msg);
  }
  throw err;
}

Prevention

When it happens

Trigger: prepare() calls readStudioRouteRoots but studioSource/routes-manifest.json is missing, unreadable, invalid JSON, or has the wrong shape.

Common situations: Deploying before the studio build ran; deploying from the wrong working directory so the path doesn't resolve; CI cache serving an empty or partial manifest.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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