mastra-ai/mastra · error · Error
Failed to complete upload: ${(err as { detail?: string }).de
Error message
Failed to complete upload: ${(err as { detail?: string }).detail || completeResp.statusText} What it means
The final step of uploadToEnvironment signals the platform that the artifact upload finished (upload-complete endpoint). A non-ok response throws with the server's `detail` when available, else statusText. The artifact bytes may already be stored, but the deploy was not finalized, so the platform may keep the deploy in an incomplete state.
Source
Thrown at packages/cli/src/commands/deploy/index.ts:398
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}`);
}
return deploy;
}
interface UnifiedDeployStatus {
id: string;
status: string;
instanceUrl: string | null;
error: string | null;
}
/**
* Poll the net-new env-scoped status endpoint until the deploy reaches a
* terminal state. Kept inside the deploy command so the unified runtime
* never reaches into ../studio/ for transport.
*/
async function streamEnvironmentDeployLogs(View on GitHub (pinned to 75dd419e61)
Solutions
- Read the `detail` in the message for the server's exact reason
- Re-run the deploy end-to-end (a fresh create/upload cycle) rather than retrying only upload-complete
- Check token validity/auth duration for long CI jobs and refresh or extend it
- Confirm no other deploy pipeline is concurrently targeting the same environment
Example fix
// before // 40-min CI job, token expires before upload-complete -> 401 // after // refresh token before deploy step (or use a token with sufficient expiry), re-run deploy
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the token won't expire mid-deploy for long CI jobs
const jobDurationMs = 40 * 60 * 1000;
const tokenTtlMs = getTokenTtl(token); // decode exp from token
if (tokenTtlMs < jobDurationMs) throw new Error('Token expires before deploy can finish; refresh it'); Type guard
function isCompleteUploadFailure(err: unknown): err is Error {
return err instanceof Error && err.message.startsWith('Failed to complete upload:');
} Try / catch
try {
const deploy = await uploadToEnvironment(args);
} catch (err) {
if (isCompleteUploadFailure(err)) {
console.error('Deploy not finalized:', err.message);
// re-run the full deploy (create + upload + complete), not just upload-complete
} else throw err;
} Prevention
- Use tokens with TTL exceeding the whole CI job duration
- Re-run the entire deploy flow after a finalize failure — don't call upload-complete standalone
- Avoid concurrent deploy pipelines on the same environment
- Log the `detail` field for platform-side support when it persists
When it happens
Trigger: The POST to /v1/projects/{projectId}/environments/{environmentId}/deploys/{deploy.id}/upload-complete returns non-2xx — e.g., server-side verification of the uploaded artifact failed, auth expired between steps, or the deploy record was cancelled/unknown.
Common situations: Token expiry mid-deploy in long CI runs; upload-complete racing server-side artifact verification; concurrent deploy superseding this one; platform-side validation rejecting an unexpected artifact layout.
Related errors
- Failed to create deploy: ${(err as { detail?: string }).deta
- 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/19860302ede42a1b.
Report an issue: GitHub.