{"record":{"id":"8bf07ef215d72e1e","repo":"mastra-ai/mastra","slug":"no-upload-url-returned","errorCode":null,"errorMessage":"No upload URL returned","messagePattern":"No upload URL returned","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/server/platform-api.ts","lineNumber":152,"sourceCode":"  const { data, error, response } = await client.POST('/v1/server/deploys', {\n    body: {\n      projectId,\n      projectName: meta?.projectName,\n      envVars: meta?.envVars,\n      ...(meta?.disablePlatformObservability !== undefined\n        ? { disablePlatformObservability: meta.disablePlatformObservability }\n        : {}),\n    },\n  });\n\n  if (error) {\n    throwApiError('Deploy failed', response.status, extractApiErrorDetail(error));\n  }\n\n  const { id, status, uploadUrl } = data;\n\n  if (!uploadUrl) {\n    throw new Error('No upload URL returned');\n  }\n\n  const cancel = (c: ReturnType<typeof createApiClient>) =>\n    bestEffortCancel({\n      postCancel: c2 => c2.POST('/v1/server/deploys/{id}/cancel', { params: { path: { id } } }),\n      client: c,\n      deployId: id,\n    });\n\n  // Step 2: Upload artifact to the signed URL\n  try {\n    if (uploadUrl.startsWith('file://')) {\n      const { writeFile } = await import('node:fs/promises');\n      const { fileURLToPath } = await import('node:url');\n      await writeFile(fileURLToPath(uploadUrl), Buffer.from(zipBuffer));\n    } else {\n      const uploadResp = await fetch(uploadUrl, {\n        method: 'PUT',","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/server/platform-api.ts#L134-L170","documentation":"uploadServerDeploy creates a deploy via POST /v1/server/deploys, which should return a signed uploadUrl where the zip artifact is PUT. If the API response succeeds (no error field) but uploadUrl is missing/empty, the CLI treats the response as malformed and throws rather than attempting an upload to an undefined URL.","triggerScenarios":"Server (or a proxy/gateway intercepting the response) returns a 2xx deploy object without uploadUrl — e.g. unexpected API version drift, a mock/dev server stub, or a response transformed/stripped by middleware; typed as present in the schema but absent at runtime.","commonSituations":"Pointing the CLI at an older/self-hosted platform build whose create-deploy response omits uploadUrl; corporate proxy rewriting responses; API contract changed while CLI is outdated (or vice versa).","solutions":["Update the CLI (`pnpm update @mastra/cli` / latest version) so its expectations match the current API","Verify you're hitting the intended platform endpoint/base URL (no stale MASTRA_BASE_URL or proxy override)","Retry — if persistent, capture the raw response (debug logs) and check the platform API version/status","Check platform service health/release notes for a deploy-create regression"],"exampleFix":"// check for stale endpoint config\n// before\nMASTRA_BASE_URL=https://old-internal-gw.example.com mastra server deploy\n// after\nunset MASTRA_BASE_URL && mastra server deploy  # use the current default API","handlingStrategy":"retry","validationCode":"// Can't validate the server's response shape beforehand, but you can sanity-check\n// the CLI/API pairing before deploying:\nconst cliVersion = (await exec('mastra --version')).trim();\nconsole.log(`CLI ${cliVersion} against API ${process.env.MASTRA_BASE_URL ?? 'default'} — ensure platform is up to date`);","typeGuard":"type DeployCreateResponse = { id: string; status: string; uploadUrl?: string };\nfunction hasUploadUrl(d: DeployCreateResponse): d is DeployCreateResponse & { uploadUrl: string } {\n  return typeof d.uploadUrl === 'string' && d.uploadUrl.length > 0;\n}","tryCatchPattern":"try {\n  await deploy();\n} catch (err) {\n  if (err instanceof Error && err.message === 'No upload URL returned') {\n    // API contract mismatch — upgrade CLI or check endpoint, then retry once\n    await exec('pnpm update -g @mastra/cli');\n    await deploy();\n  } else throw err;\n}","preventionTips":["Keep the CLI and platform on compatible versions","Avoid proxies/middleware that transform API JSON responses","Verify MASTRA_BASE_URL points at the supported platform endpoint","Report persistent occurrences with raw response debug logs"],"tags":["api","upload","contract-mismatch"],"backgroundTag":"api-response-missing-field","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}