mastra-ai/mastra · error
Failed to copy studio assets from "${studioSource}" to "${st
Error message
Failed to copy studio assets from "${studioSource}" to "${staticDir}": ${err instanceof Error ? err.message : err} What it means
The Vercel deployer's prepare() copies prebuilt studio static assets into the Vercel output static directory (.vercel/output/static). If the copy operation fails for any reason (missing source, permissions, disk error), it wraps the underlying error in this descriptive message so you know which step of deployment failed.
Source
Thrown at deployers/vercel/src/index.ts:63
await super.prepare(outputDirectory);
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const studioSource = join(dirname(__dirname), 'dist', 'studio');
this.writeVercelJSON(
join(outputDirectory, this.outputDir, '..', '..'),
this.studio ? this.readStudioRouteRoots(studioSource) : [],
);
if (this.studio) {
const staticDir = join(outputDirectory, '.vercel', 'output', 'static');
try {
await copy(studioSource, staticDir, { overwrite: true });
} catch (err) {
throw new Error(
`Failed to copy studio assets from "${studioSource}" to "${staticDir}": ${err instanceof Error ? err.message : err}`,
);
}
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'));View on GitHub (pinned to 75dd419e61)
Solutions
- Build the studio so studioSource exists before running the Vercel deployer.
- Check the inner error (the message includes err.message) and fix the root cause (permissions, disk space).
- Ensure .vercel/output/static is writable and not locked by another process.
- Verify the outputDirectory option points to the correct build directory.
Example fix
// before npx vercel deploy # studio never built // after pnpm build:studio && npx vercel deploy
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
if (!existsSync(studioSource)) {
throw new Error(`Studio assets not built: ${studioSource} missing. Run the studio build first.`);
} Type guard
function isNodeError(err: unknown): err is Error {
return err instanceof Error;
} Try / catch
try {
await deployer.prepare();
} catch (err) {
if (String((err as Error).message).startsWith('Failed to copy studio assets')) {
console.error('Studio build missing or copy failed:', (err as Error).message);
// rebuild studio then retry
}
throw err;
} Prevention
- Always build the studio before invoking the Vercel deployer.
- Add a build-order check in CI (studio build must precede deploy).
- Verify write permissions on .vercel/output/static.
- Read the inner err.message embedded in the error for the root cause.
When it happens
Trigger: Deploying with this.studio enabled while studioSource does not exist (studio not built first), or copy() failing due to permissions, ENOSPC, or EBUSY on .vercel/output/static.
Common situations: Forgetting to run the studio build before deploying; deploying from a container/user without write access to the output directory; stale file locks in CI.
Related errors
- Failed to read studio routes manifest at "${manifestPath}":
- Missing required file, checked the following paths: ${files.
- Failed to copy studio assets from "${studioSource}" to "${st
- expected an array of route segments
- .mastra/output/index.mjs not found — did the build succeed?
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4c75d83bff5cccb7.
Report an issue: GitHub.