mastra-ai/mastra · error · Error

.mastra/output/index.mjs not found — did the build succeed?

Error message

.mastra/output/index.mjs not found — did the build succeed?

What it means

After building, deploy verifies the bundled entrypoint `.mastra/output/index.mjs` exists via fs access. If it does not, the build silently failed or produced output elsewhere, and the command throws before attempting upload — deploying a missing artifact would always fail server-side.

Source

Thrown at packages/cli/src/commands/studio/deploy.ts:556

  } else if (staleness.isStale) {
    // Build is stale or doesn't exist — rebuild
    t = performance.now();
    if (staleness.reason === 'hash-mismatch') {
      p.log.step('Source files changed, rebuilding...');
    }
    await runBuild(targetDir, { debug: opts.debug });
    p.log.step(`Build completed (${elapsed(performance.now() - t)})`);
  } else {
    // Build is up-to-date — skip rebuild
    p.log.step('Build is up-to-date, skipping rebuild');
  }

  // Verify build output exists
  const outputEntry = join(targetDir, '.mastra', 'output', 'index.mjs');
  try {
    await access(outputEntry);
  } catch {
    throw new Error('.mastra/output/index.mjs not found — did the build succeed?');
  }

  // If the user didn't pass --env-file and no ambient .env* file exists,
  // skip the local env-var upload entirely and let the platform use the
  // env vars stored on the project. The server-side deploy handler merges
  // request envVars over the stored vars, so an empty (absent) envVars
  // payload cleanly falls back to what's already stored.
  let envVars: Record<string, string> = {};
  const hasEnvFile = opts.envFile ? true : (await getDeployEnvFiles(targetDir)).length > 0;
  if (hasEnvFile) {
    envVars = await readEnvVars(targetDir, { autoAccept, envFile: opts.envFile });
  }
  const envCount = Object.keys(envVars).length;
  if (envCount > 0) {
    p.log.step(`Found ${envCount} env var(s)`);
  } else if (hasEnvFile) {
    p.log.step('No env vars found in selected env file');
  } else {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Run `mastra build` first and fix any build errors it reports
  2. Ensure deploy runs in the same directory (targetDir) where the build wrote .mastra/output/index.mjs
  3. Check for build script failures in CI logs (remove error-swallowing like `|| true`)
  4. Clear .mastra and rebuild if output was partially cleaned or cached
  5. If using custom output config, point it back to .mastra/output or pass the correct dir to deploy

Example fix

// before (CI)
- run: mastra studio deploy --yes
// after
- run: mastra build
- run: ls .mastra/output/index.mjs
- run: mastra studio deploy --yes
Defensive patterns

Strategy: validation

Validate before calling

import { access } from 'node:fs/promises';
const entry = join(deployDir, '.mastra', 'output', 'index.mjs');
try { await access(entry); } catch {
  throw new Error('Run `mastra build` before deploy; .mastra/output/index.mjs is missing.');
}

Try / catch

try {
  await studioDeploy();
} catch (e) {
  if (e instanceof Error && e.message.includes('index.mjs not found')) {
    console.error('Build first: `mastra build`. Inspect build logs for silent failures.');
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: `mastra deploy`/`mastra build` step failed or was skipped; building in a different directory than targetDir; custom build output configuration redirecting output away from .mastra/output; a partially cleaned .mastra directory.

Common situations: CI caches restoring a stale/empty .mastra folder; TypeScript/build errors swallowed by `|| true` in scripts; running deploy before ever running build; monorepo cwd mismatch so deploy checks the wrong directory.

Related errors


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