jackwener/OpenCLI · critical · CommandExecutionError
TOS upload part ${partNumber} failed with status ${res.statu
Error message
TOS upload part ${partNumber} failed with status ${res.status}: ${res.body} What it means
uploadPart PUTs one part of the file to TOS and expects HTTP 200 with parsed.code === 2000 (application-level success). This CommandExecutionError is thrown when either the HTTP status or the JSON code indicates the part upload was rejected.
Source
Thrown at clis/douyin/_shared/tos-upload.js:230
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',
};
const res = await tosRequest({ method: 'POST', url, headers, body: data });
let parsed;
try {
parsed = JSON.parse(res.body);
}
catch {
parsed = null;
}
if (res.status !== 200 || parsed?.code !== 2000) {
throw new CommandExecutionError(`TOS upload part ${partNumber} failed with status ${res.status}: ${res.body}`, 'Check that TOS upload authorization is valid and not expired.');
}
return parsed?.data?.crc32 || crc32;
}
// ── Phase 3: Complete multipart upload ───────────────────────────────────────
async function completeMultipartUpload(tosUrl, uploadId, parts, auth, uploadHeader, userId) {
const url = `${gatewayBaseUrl(tosUrl)}?uploadmode=part&phase=finish&uploadid=${encodeURIComponent(uploadId)}`;
const body = parts
.sort((a, b) => a.partNumber - b.partNumber)
.map(p => `${p.partNumber}:${p.crc32}`)
.join(',');
const res = await tosRequest({
method: 'POST',
url,
headers: gatewayHeaders(auth, uploadHeader, userId),
body,
});
let parsed;
try {View on GitHub (pinned to 49907e53dc)
Solutions
- Re-fetch upload authorization and restart/resume the upload
- Retry the failing part with backoff (transient network errors)
- Check res.body for server-side reason (throttle, auth, signature)
- Verify the part buffer and crc32Hex computation are correct and the file wasn't modified mid-upload
Example fix
// before
await uploadPart(tosUrl, partNumber, uploadId, buffer, auth, uploadHeader, userId);
// after
for (let i = 0; i < 3; i++) {
try { return await uploadPart(tosUrl, partNumber, uploadId, buffer, auth, uploadHeader, userId); }
catch (e) { await sleep(1000 * 2 ** i); }
}
throw new Error('part upload failed after retries'); Defensive patterns
Strategy: retry
Validate before calling
// Pre-check upload info freshness before the part loop
if (!uploadInfo || !uploadInfo.auth) throw new Error('missing TOS auth before part upload'); Try / catch
try { await uploadPart(tosUrl, partNumber, uploadId, buffer, auth, uploadHeader, userId); }
catch (e) {
if (String(e.message).startsWith('TOS upload part')) {
await sleep(2000);
await uploadPart(tosUrl, partNumber, uploadId, buffer, auth, uploadHeader, userId); // resume state keeps progress
} else throw e;
} Prevention
- Rely on the library's resume state to re-send only failed parts
- Add bounded exponential-backoff retries around part uploads
- Keep the file unmodified during upload so CRC32 matches
- Re-acquire auth for very large files whose upload outlives the token TTL
When it happens
Trigger: tosUpload loop -> uploadPart with a part buffer; server returns non-200, or 200 with body code != 2000 — expired auth mid-upload, wrong CRC32 handling, throttling, or part-data corruption.
Common situations: Long uploads where the TOS auth expires between init and later parts; network interruptions; resuming with a stale uploadId after server-side cleanup.
Related errors
- TOS init multipart upload failed with status ${res.status}:
- TOS complete multipart upload failed with status ${res.statu
- Cover image file not found: ${imagePath}
- ImageX upload failed with status ${res.status}: ${body}
- TOS init response missing UploadId: ${res.body}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/187bc58886db2c68.
Report an issue: GitHub.