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

Thrown by runUnifiedDeploy after the build step completes, when it verifies that the build entry point .mastra/output/index.mjs exists via fs.access. If the file is missing, the build either did not run, failed silently, or wrote output elsewhere — so the CLI refuses to package and upload an incomplete deploy. The message explicitly suggests checking whether the build succeeded.

Source

Thrown at packages/cli/src/commands/deploy/index.ts:748

    }
    p.log.step('Skipping build (--skip-build)');
  } else if (staleness.isStale) {
    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 {
    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?');
  }

  // Auto-select .env.<envName> when deploying to a named environment
  // (e.g. --env staging auto-selects .env.staging if it exists).
  //
  // envName comes from the --env CLI flag, so we validate it before
  // interpolating it into a file path. Only simple environment identifiers
  // (letters, digits, dot, dash, underscore) are allowed; anything with a
  // path separator or `..` traversal segment is ignored. This keeps a
  // hostile --env value from escaping the project directory and being read
  // (and re-uploaded) via readEnvVars.
  let envFile = opts.envFile;
  if (!envFile && /^[a-zA-Z0-9._-]+$/.test(envName) && !envName.includes('..')) {
    const envNameFile = `.env.${envName}`;
    const candidate = resolve(targetDir, envNameFile);
    const targetPrefix = resolve(targetDir) + '/';
    if (candidate.startsWith(targetPrefix)) {
      try {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Run `mastra build` first (or re-run `mastra deploy` watching the build output for errors) and fix any build failures.
  2. Confirm you are deploying from the project root that contains the .mastra directory (pass the correct dir argument).
  3. Inspect .mastra/output to see what the build actually produced; check for custom output config redirecting the entry file.
  4. Clear .mastra/output and rebuild to eliminate stale/corrupted artifacts; verify your @mastra/core and CLI versions are in sync.

Example fix

// before: deploying without a valid build output
$ mastra deploy
Error: .mastra/output/index.mjs not found — did the build succeed?
// after: build first, then deploy
$ mastra build
$ ls .mastra/output/index.mjs
$ mastra deploy
Defensive patterns

Strategy: validation

Validate before calling

import { access } from 'node:fs/promises';
try {
  await access('.mastra/output/index.mjs');
} catch {
  throw new Error('Run `mastra build` before `mastra deploy`');
}

Prevention

When it happens

Trigger: fs.access(join(targetDir, '.mastra', 'output', 'index.mjs')) rejects after the build phase. Occurs when the build command failed but the deploy continued, the build produced a different entry (e.g. index.js, or a non-bundled output), or a stale/cleaned .mastra directory.

Common situations: Build step failed earlier but errors were swallowed or scrolled past; running `mastra deploy` without `mastra build` in setups that expect a separate build; custom output configuration redirecting the bundle away from .mastra/output; running deploy from the wrong directory; stale .mastra/output removed by a git clean or CI cache reset; Mastra version changes altering the output path.

Related errors


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