jackwener/OpenCLI · error · CommandExecutionError
Image upload did not complete before timeout
Error message
Image upload did not complete before timeout
What it means
Thrown when the image upload either never finished within UPLOAD_TIMEOUT_MS (30s, polled every 1.5s) or the page's own polling code reported a failure via uploadResult.message. The command waits for Weibo to confirm all uploaded images (expected count = absPaths.length) before inserting text and publishing.
Source
Thrown at clis/weibo/publish.js:196
// Wait for upload to complete
let uploadResult = null;
for (let i = 0; i < Math.ceil(UPLOAD_TIMEOUT_MS / UPLOAD_POLL_MS); i++) {
await page.wait({ time: UPLOAD_POLL_MS / 1000 });
uploadResult = await page.evaluateWithArgs(`
(() => {
const expectedCount = expected;
const uploading = document.querySelector('[class*="upload"], [class*="progress"]');
if (uploading && uploading.offsetParent !== null) return null;
const pics = document.querySelectorAll('img[class*="pic"], [class*="imgItem"], [class*="picture"] img');
if (pics.length >= expectedCount) return { ok: true, count: pics.length };
return null;
})()
`, { expected: absPaths.length });
if (uploadResult !== null) break;
}
if (!uploadResult?.ok) {
throw new CommandExecutionError(uploadResult?.message ?? 'Image upload did not complete before timeout');
}
}
// Step 6: Insert text using native DOM setter (preserves Weibo internal state)
// IMPORTANT: Using nativeSetter preserves the textarea's reactive/internal state.
// Direct ta.value= assignment bypasses Weibo's Vue reactivity and causes "undefined" content.
const insertResult = await page.evaluateWithArgs(`
((selectors) => {
let ta = null;
for (const sel of selectors) {
for (const t of document.querySelectorAll(sel)) {
if (t.offsetParent !== null) ta = t;
}
}
if (!ta) return { ok: false, message: 'textarea not visible' };
ta.focus();
const nativeSetter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set;
if (nativeSetter) {View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the publish — transient network slowness is the most common cause
- Reduce image count and/or use smaller/compressed images so uploads finish within 30s
- Check the accompanying uploadResult.message for Weibo's specific rejection reason and fix that (e.g. image too large)
- Verify the images load and are valid jpg/png/gif/webp before invoking
Defensive patterns
Strategy: retry
Validate before calling
for (const p of paths) {
const stat = fs.statSync(p, { throwIfNoEntry: false });
if (!stat || stat.size > 5 * 1024 * 1024) {
console.warn(`${p} is missing or larger than 5MB — upload may time out`);
}
} Try / catch
try {
await publishToWeibo(text, images);
} catch (err) {
if (String(err.message).includes('upload did not complete')) {
await new Promise(r => setTimeout(r, 5000));
await publishToWeibo(text, images); // one retry
} else throw err;
} Prevention
- Compress images before uploading so each finishes well within 30s
- Limit to 1–4 images for automations over slow links
- Avoid running publishes over high-latency proxies/VPNs
- Check image validity (correct extension, non-zero size) beforehand
When it happens
Trigger: page.evaluate poll loop returns uploadResult that is null/ok:false, or keeps returning null until the poll budget expires; then `uploadResult?.ok` is falsy and this error is raised with uploadResult.message or the fallback text.
Common situations: Slow or proxied network where a large image takes >30s to upload to Weibo's CDN; Weibo rate-limiting or rejecting an image (size, dimensions); the file input accepted files but Weibo's uploader hit a client-side error; too many images at once (up to 9).
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- weibo delete: HTTP ${result.status}
- 12306 queryByTrainNo returned HTTP ${resp.status}
- 12306 queryByTrainNo returned non-JSON body
- 12306 ${endpoint} returned non-JSON body
- 12306 ${endpoint} returned an unexpected payload shape
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0deac440f3f2c9cc.
Report an issue: GitHub.