mastra-ai/mastra · error · Error
Failed to upload artifact: ${uploadResp.statusText}
Error message
Failed to upload artifact: ${uploadResp.statusText} What it means
After creating the deploy record, uploadToEnvironment PUTs/POSTs the zip artifact to the returned uploadUrl. A non-ok response here throws with only the HTTP statusText (this endpoint is a raw upload sink that typically returns no JSON body). It means the storage upload itself failed — network, credentials, or an expired presigned URL.
Source
Thrown at packages/cli/src/commands/deploy/index.ts:380
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
// unified-runtime CLI never touches /v1/studio/*.
const completeResp = await fetch(
`${apiUrl}/v1/projects/${projectId}/environments/${environmentId}/deploys/${deploy.id}/upload-complete`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'x-organization-id': orgId,
},
},
);
if (!completeResp.ok) {
const err = await completeResp.json().catch(() => ({}));
throw new Error(`Failed to complete upload: ${(err as { detail?: string }).detail || completeResp.statusText}`);View on GitHub (pinned to 75dd419e61)
Solutions
- Retry the deploy — presigned-URL or transient storage failures usually clear on retry
- Reduce artifact size (exclude node_modules/dev assets from the zip) if statusText suggests a size limit (413)
- Deploy again promptly after deploy creation so the signed upload URL doesn't expire
- Check network/proxy egress to the storage host from your CI environment
Example fix
// before // zip includes node_modules -> 413 Payload Too Large // after // build step: zip only dist/ + package.json, then retry deploy
Defensive patterns
Strategy: retry
Validate before calling
// Check artifact size before upload (guard against 413)
const MAX_ZIP_BYTES = 100 * 1024 * 1024;
if (zipBuffer.byteLength > MAX_ZIP_BYTES) {
throw new Error('Artifact ' + zipBuffer.byteLength + ' bytes exceeds upload limit');
} Type guard
function isUploadFailure(err: unknown): err is Error {
return err instanceof Error && err.message.startsWith('Failed to upload artifact:');
} Try / catch
try {
const deploy = await uploadToEnvironment(args);
} catch (err) {
if (isUploadFailure(err) && isRetryableStatus(err.message)) {
await uploadToEnvironment(args); // one retry for transient storage/network errors
} else throw err;
} Prevention
- Keep artifacts small: zip only dist/ and manifests, never node_modules
- Upload immediately after deploy creation so the signed URL doesn't expire
- Ensure CI egress allows the storage upload host
- Retry once on transient 5xx/timeouts before failing the pipeline
When it happens
Trigger: The artifact upload fetch to deploy.uploadUrl returns a non-2xx status — e.g., 403 on an expired signed URL, 413 for an oversized zip, 5xx from storage, or an interrupted/unreachable connection reported via statusText.
Common situations: Slow CI networks or large bundles causing storage timeouts; zip exceeding upload size limits; long delay between deploy creation and upload letting the presigned URL lapse; proxy/firewall blocking the storage host.
Related errors
- Artifact upload failed: ${uploadResp.status} ${uploadResp.st
- Artifact upload failed: ${uploadResp.status} ${uploadResp.st
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
- Failed to stream background tasks: ${response.statusText}
- Failed to stream agent builder action: ${response.statusText
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/f9e8894d40dfcf24.
Report an issue: GitHub.