jackwener/OpenCLI · error · CommandExecutionError

Instagram image upload failed

Error message

Instagram image upload failed

What it means

waitForPreview polls inspectUploadStage after the image file input is set, waiting for Instagram to render an upload preview. If Instagram reports a failed upload state, a debug screenshot is saved to /tmp/instagram_post_preview_debug.png and a CommandExecutionError (wrapped by makeUploadFailure as 'Instagram image upload failed') is thrown. It also throws if no preview appears after all polling attempts.

Source

Thrown at clis/instagram/post.js:776

        if (retry instanceof HTMLElement) {
          retry.click();
          return { ok: true };
        }
      }
      return { ok: false };
    })()
  `);
    return !!result?.ok;
}
async function waitForPreview(page, maxWaitSeconds = 12) {
    const attempts = Math.max(1, Math.ceil(maxWaitSeconds));
    for (let attempt = 0; attempt < attempts; attempt++) {
        const state = await inspectUploadStage(page);
        if (state.state === 'preview')
            return;
        if (state.state === 'failed') {
            await page.screenshot({ path: '/tmp/instagram_post_preview_debug.png' });
            throw makeUploadFailure('Inspect /tmp/instagram_post_preview_debug.png. ' + (state.detail || ''));
        }
        if (attempt < attempts - 1)
            await page.wait({ time: 1 });
    }
    await page.screenshot({ path: '/tmp/instagram_post_preview_debug.png' });
    throw new CommandExecutionError('Instagram image preview did not appear after upload', 'The selected file input may not match the active composer; inspect /tmp/instagram_post_preview_debug.png');
}
async function waitForPreviewMaybe(page, maxWaitSeconds = 4) {
    const attempts = Math.max(1, Math.ceil(maxWaitSeconds * 2));
    for (let attempt = 0; attempt < attempts; attempt++) {
        const state = await inspectUploadStage(page);
        if (state.state !== 'pending')
            return state;
        if (attempt < attempts - 1)
            await page.wait({ time: 0.5 });
    }
    return { state: 'pending' };
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect /tmp/instagram_post_preview_debug.png to see what the page actually shows
  2. Convert the image to a supported format (JPG/PNG) and reasonable size, then retry
  3. Retry the upload; transient network slowness often exceeds the poll window
  4. Update the CLI if Instagram changed its composer DOM so inspectUploadStage detects the preview again

Example fix

// before
const buf = fs.readFileSync('photo.heic');
await postImage(page, buf);
// after
const jpg = await sharp('photo.heic').jpeg({ quality: 90 }).toBuffer();
await postImage(page, jpg);
Defensive patterns

Strategy: validation

Validate before calling

const stat = fs.statSync(file);
const okType = /\.(jpe?g|png|webp)$/i.test(file);
const okSize = stat.size > 0 && stat.size < 8 * 1024 * 1024;
if (!okType || !okSize) throw new Error('image must be jpg/png/webp under 8MB: ' + file);

Type guard

function isUploadableImage(file) {
  return /^image\/(jpe?g|png|webp)$/.test(mimeLookup(file));
}

Try / catch

try {
  await instagramPost(page, file);
} catch (e) {
  if (/Instagram image upload failed/.test(e.message)) {
    console.error('see /tmp/instagram_post_preview_debug.png', e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the instagram post/upload flow when the uploaded file is rejected by Instagram (unsupported format/size) or the composer never renders a preview element within the polling window.

Common situations: Uploading an unsupported image (wrong mime, corrupt file, oversized), selecting a file input that does not match the active composer (wrong modal/tab), Instagram DOM changes that break stage detection, slow network making the preview exceed the timeout.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/682a7bf26d355b51. Report an issue: GitHub.