jackwener/OpenCLI · critical · CommandExecutionError
TOS init multipart upload failed with status ${res.status}:
Error message
TOS init multipart upload failed with status ${res.status}: ${res.body} What it means
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.
Source
Thrown at clis/douyin/_shared/tos-upload.js:202
|| json?.UploadId
|| json?.uploadID
|| json?.uploadId
|| null;
}
catch {
return null;
}
}
// ── Phase 1: Init multipart upload ───────────────────────────────────────────
async function initMultipartUpload(tosUrl, auth, uploadHeader, userId) {
const initUrl = `${gatewayBaseUrl(tosUrl)}?uploadmode=part&phase=init`;
const res = await tosRequest({
method: 'POST',
url: initUrl,
headers: gatewayHeaders(auth, uploadHeader, userId),
});
if (res.status !== 200) {
throw new CommandExecutionError(`TOS init multipart upload failed with status ${res.status}: ${res.body}`, 'Check that TOS upload authorization is valid and not expired.');
}
const uploadId = extractUploadId(res.body);
if (!uploadId) {
throw new CommandExecutionError(`TOS init response missing UploadId: ${res.body}`);
}
return uploadId;
}
// ── Phase 2: Upload a single part ────────────────────────────────────────────
async function uploadPart(tosUrl, partNumber, uploadId, data, auth, uploadHeader, userId) {
const crc32 = crc32Hex(data);
const url = `${gatewayBaseUrl(tosUrl)}?uploadid=${encodeURIComponent(uploadId)}&part_number=${partNumber}&phase=transfer`;
const headers = {
...gatewayHeaders(auth, uploadHeader, userId),
'Content-CRC32': crc32,
'Content-Type': 'application/octet-stream',
'X-Use-Init-Upload-Optimize': '1',
'X-Use-Large-Local-Cache': '1',
};View on GitHub (pinned to 49907e53dc)
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
Example fix
// before
await tosUpload({ filePath, uploadInfo: staleUploadInfo });
// after
const uploadInfo = await getUploadAuthV5Credentials(page); // fresh auth
await tosUpload({ filePath, uploadInfo }); Defensive patterns
Strategy: retry
Validate before calling
function canAttemptUpload(uploadInfo) {
return Boolean(uploadInfo && uploadInfo.tos_upload_url && uploadInfo.auth && uploadInfo.upload_header && uploadInfo.user_id);
} Type guard
function hasFreshUploadInfo(u) {
return !!u && typeof u === 'object' && typeof u.tos_upload_url === 'string' &&
u.tos_upload_url.startsWith('https://') && !!u.auth;
} Try / catch
try { await tosUpload(options); }
catch (e) {
if (String(e.message).startsWith('TOS init multipart upload failed')) {
const fresh = await getUploadAuthV5Credentials(page);
await tosUpload({ ...options, uploadInfo: fresh });
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Stale uploadInfo obtained long before upload (auth expired); logged-out Douyin session; network/proxy intercepting the POST; wrong region extracted from host.
Related errors
- TOS upload part ${partNumber} failed with status ${res.statu
- TOS complete multipart upload failed with status ${res.statu
- 获取抖音上传授权失败: ${JSON.stringify(result)}
- Douyin API auth/permission error ${code} at ${method} ${url}
- Cover image file not found: ${imagePath}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2d3254fe0b549e37.
Report an issue: GitHub.