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 theView on GitHub (pinned to 75dd419e61)
Solutions
- Read the `detail` in the message — it usually names the exact server-side rejection cause
- Verify the token is valid and has deploy permission for projectId/environmentId
- Confirm --project and environment identifiers are correct and current
- 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
- Keep tokens fresh and scoped to the target project/environment
- Validate projectId/environmentId before deploying
- Check platform status/limits if rejects are quota-shaped (429/413)
- Upgrade the CLI after platform API version bumps to stay contract-compatible
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
- Failed to complete upload: ${(err as { detail?: string }).de
- Perplexity Search request failed with status ${response.stat
- Request failed (${response.status}) / server-provided messag
- Request failed (${res.status}) / server-provided message
- Failed to load pull request subscriptions (${response.status
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/7f5ab117038f7e18.
Report an issue: GitHub.