mastra-ai/mastra · error · Error

Failed to create deploy: ${(err as { detail?: string }).deta

Error message

Failed to create deploy: ${(err as { detail?: string }).detail || createResp.statusText}

What it means

uploadToEnvironment first POSTs a deploy-creation request to the platform API. If the response is not ok, the CLI parses the JSON body and throws with the server-provided `detail` field, falling back to the HTTP statusText when the body has no detail or isn't JSON. This is the API rejecting deploy creation (auth, validation, limits), surfaced as-is for diagnosis.

Source

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

  };
  if (opts.gitBranch) createHeaders['x-git-branch'] = opts.gitBranch;
  if (opts.mastraVersion) createHeaders['x-mastra-version'] = opts.mastraVersion;

  const createBody: Record<string, unknown> = {};
  if (opts.envVars) createBody.envVars = opts.envVars;
  if (opts.disablePlatformObservability !== undefined) {
    createBody.disablePlatformObservability = opts.disablePlatformObservability;
  }

  const createResp = await fetch(`${apiUrl}/v1/projects/${projectId}/environments/${environmentId}/deploy`, {
    method: 'POST',
    headers: createHeaders,
    body: JSON.stringify(createBody),
  });

  if (!createResp.ok) {
    const err = await createResp.json().catch(() => ({}));
    throw new Error(`Failed to create deploy: ${(err as { detail?: string }).detail || createResp.statusText}`);
  }

  const { deploy } = (await createResp.json()) as { deploy: { id: string; uploadUrl: string } };

  // Upload artifact
  const uploadResp = await fetch(deploy.uploadUrl, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/zip',
    },
    body: zipBuffer,
  });

  if (!uploadResp.ok) {
    throw new Error(`Failed to upload artifact: ${uploadResp.statusText}`);
  }

  // Signal upload complete — uses net-new env-scoped endpoint so the

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Read the `detail` in the message — it usually names the exact server-side rejection cause
  2. Verify the token is valid and has deploy permission for projectId/environmentId
  3. Confirm --project and environment identifiers are correct and current
  4. Re-check API compatibility (CLI vs platform version) and upgrade the CLI if the endpoint contract changed

Example fix

// before
await uploadToEnvironment({ environmentId: 'env-old' }); // 404, detail: 'environment not found'
// after
await uploadToEnvironment({ environmentId: 'env-current-id' }); // valid environment
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: verify auth and target identifiers before creating the deploy
if (!token) throw new Error('Missing API token for deploy');
if (!projectId || !environmentId) throw new Error('projectId and environmentId are required');

Type guard

function hasDeployErrorDetail(err: unknown): err is { detail: string } {
  return typeof err === 'object' && err !== null && typeof (err as { detail?: unknown }).detail === 'string';
}

Try / catch

try {
  const deploy = await uploadToEnvironment(args);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Failed to create deploy:')) {
    const detail = err.message.slice('Failed to create deploy:'.length).trim();
    console.error('Server rejected deploy creation:', detail);
  } else throw err;
}

Prevention

When it happens

Trigger: The create-deploy POST returns a non-2xx response — e.g., 401/403 auth problems, invalid environmentId/projectId, deploy quota exceeded, or malformed createBody rejected by validation — and the thrown message reflects err.detail or statusText.

Common situations: Expired or scoped-out CI token; deploying to an environment id that doesn't exist or belongs to another project; payload exceeding size/limits; API version drift after a CLI or platform upgrade.

Related errors


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