{"record":{"id":"2d3254fe0b549e37","repo":"jackwener/OpenCLI","slug":"tos-init-multipart-upload-failed-with-status-res","errorCode":null,"errorMessage":"TOS init multipart upload failed with status ${res.status}: ${res.body}","messagePattern":"TOS init multipart upload failed with status (.+?): (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"critical","filePath":"clis/douyin/_shared/tos-upload.js","lineNumber":202,"sourceCode":"            || json?.UploadId\n            || json?.uploadID\n            || json?.uploadId\n            || null;\n    }\n    catch {\n        return null;\n    }\n}\n// ── Phase 1: Init multipart upload ───────────────────────────────────────────\nasync function initMultipartUpload(tosUrl, auth, uploadHeader, userId) {\n    const initUrl = `${gatewayBaseUrl(tosUrl)}?uploadmode=part&phase=init`;\n    const res = await tosRequest({\n        method: 'POST',\n        url: initUrl,\n        headers: gatewayHeaders(auth, uploadHeader, userId),\n    });\n    if (res.status !== 200) {\n        throw new CommandExecutionError(`TOS init multipart upload failed with status ${res.status}: ${res.body}`, 'Check that TOS upload authorization is valid and not expired.');\n    }\n    const uploadId = extractUploadId(res.body);\n    if (!uploadId) {\n        throw new CommandExecutionError(`TOS init response missing UploadId: ${res.body}`);\n    }\n    return uploadId;\n}\n// ── Phase 2: Upload a single part ────────────────────────────────────────────\nasync function uploadPart(tosUrl, partNumber, uploadId, data, auth, uploadHeader, userId) {\n    const crc32 = crc32Hex(data);\n    const url = `${gatewayBaseUrl(tosUrl)}?uploadid=${encodeURIComponent(uploadId)}&part_number=${partNumber}&phase=transfer`;\n    const headers = {\n        ...gatewayHeaders(auth, uploadHeader, userId),\n        'Content-CRC32': crc32,\n        'Content-Type': 'application/octet-stream',\n        'X-Use-Init-Upload-Optimize': '1',\n        'X-Use-Large-Local-Cache': '1',\n    };","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/_shared/tos-upload.js#L184-L220","documentation":"initMultipartUpload starts a TOS (Toutiao Object Storage) multipart upload via the gateway and throws this CommandExecutionError when the POST init-phase request returns a non-200 HTTP status. It signals the upload session could not be created at all, so no parts can be uploaded.","triggerScenarios":"tosUpload -> initMultipartUpload posts to `${tosUrl}?uploadmode=part&phase=init` and receives HTTP 4xx/5xx, typically because the auth token/upload_header from the upload authorization is expired, or the tos_upload_url/region is wrong.","commonSituations":"Stale uploadInfo obtained long before upload (auth expired); logged-out Douyin session; network/proxy intercepting the POST; wrong region extracted from host.","solutions":["Re-fetch fresh upload authorization (getUploadAuthV5Credentials / upload info) and retry the upload","Check the douyin session is logged in and cookies are valid","Inspect res.body in the message for the server's error reason and act on it","Verify network/proxy allows POST to the TOS gateway host"],"exampleFix":"// before\nawait tosUpload({ filePath, uploadInfo: staleUploadInfo });\n// after\nconst uploadInfo = await getUploadAuthV5Credentials(page); // fresh auth\nawait tosUpload({ filePath, uploadInfo });","handlingStrategy":"retry","validationCode":"function canAttemptUpload(uploadInfo) {\n  return Boolean(uploadInfo && uploadInfo.tos_upload_url && uploadInfo.auth && uploadInfo.upload_header && uploadInfo.user_id);\n}","typeGuard":"function hasFreshUploadInfo(u) {\n  return !!u && typeof u === 'object' && typeof u.tos_upload_url === 'string' &&\n    u.tos_upload_url.startsWith('https://') && !!u.auth;\n}","tryCatchPattern":"try { await tosUpload(options); }\ncatch (e) {\n  if (String(e.message).startsWith('TOS init multipart upload failed')) {\n    const fresh = await getUploadAuthV5Credentials(page);\n    await tosUpload({ ...options, uploadInfo: fresh });\n  } else throw e;\n}","preventionTips":["Always fetch upload authorization immediately before uploading","Check auth expiry/TTL if the upload info is cached","Log response bodies from TOS calls for diagnosis","Handle 401/403 by refreshing the douyin login session"],"tags":["http","upload","auth","douyin"],"backgroundTag":"upload-init-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}