jackwener/OpenCLI · error · CommandExecutionError

Instagram reel ${expected} editor did not appear

Error message

Instagram reel ${expected} editor did not appear

What it means

After maxWaitSeconds of polling without the reel DOM reaching the `expected` stage — and without an explicit 'failed' state — waitForReelStage throws this templated timeout error naming the stage. It indicates the editor stage (e.g. 'caption', 'share') simply never appeared in time, with no explicit Instagram failure dialog.

Source

Thrown at clis/instagram/reel.js:283

      if (/crop|select crop|open media gallery/.test(lower) && hasVisibleButton(['next'])) {
        return { state: 'crop', detail: text };
      }
      return { state: 'pending', detail: text };
    })()
  `;
}
async function waitForReelStage(page, expected, maxWaitSeconds = 20) {
    for (let attempt = 0; attempt < maxWaitSeconds * 2; attempt += 1) {
        const result = await page.evaluate(buildInspectReelStageJs());
        if (result?.state === expected)
            return;
        if (result?.state === 'failed') {
            throw new CommandExecutionError('Instagram reel editor did not appear', result.detail ? `Instagram reel flow failed: ${result.detail}` : 'Instagram reel flow failed before the next editor stage');
        }
        if (attempt < maxWaitSeconds * 2 - 1)
            await page.wait({ time: 0.5 });
    }
    throw new CommandExecutionError(`Instagram reel ${expected} editor did not appear`);
}
async function focusCaptionEditor(page) {
    const result = await page.evaluate(`
    (() => {
      const isVisible = (el) => {
        if (!(el instanceof HTMLElement)) return false;
        const style = window.getComputedStyle(el);
        const rect = el.getBoundingClientRect();
        return style.display !== 'none'
          && style.visibility !== 'hidden'
          && rect.width > 0
          && rect.height > 0;
      };
      const dialogs = Array.from(document.querySelectorAll('[role="dialog"]')).filter((el) => isVisible(el));
      for (const dialog of dialogs) {
        const textarea = dialog.querySelector('[aria-label="Write a caption..."], textarea');
        if (textarea instanceof HTMLTextAreaElement && isVisible(textarea)) {
          textarea.focus();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Capture a screenshot at timeout (add one like waitForVideoPreview does) to see the actual page state.
  2. Increase the maxWaitSeconds argument for slower environments.
  3. Broaden buildInspectReelStageJs detection to match the current editor DOM/labels.
  4. Dismiss or handle any blocking dialogs (consent/notification prompts) before polling.
  5. Retry the flow; transient render delays often resolve on a second run.

Example fix

// before
await waitForReelStage(page, 'share'); // default 20s
// after
await waitForReelStage(page, 'share', 60); // give slow loads time to render
Defensive patterns

Strategy: retry

Validate before calling

// Dismiss known blocking prompts before waiting for the editor stage
await clickActionMaybe(page, ['Allow all cookies', 'Allow', 'Not now', 'Next']);

Type guard

function isExpectedStage(r, expected) {
  return !!r && typeof r === 'object' &&
    (r.state === expected || r.state === 'failed') &&
    (r.detail === undefined || typeof r.detail === 'string');
}

Try / catch

try {
  await waitForReelStage(page, expected, 20);
} catch (err) {
  if (String(err.message).includes('editor did not appear')) {
    await page.screenshot({ path: '/tmp/ig_stage_timeout.png' });
    // retry once after handling whatever the screenshot shows
    await waitForReelStage(page, expected, 60);
  } else throw err;
}

Prevention

When it happens

Trigger: The for-loop in waitForReelStage exhausts all maxWaitSeconds*2 attempts while buildInspectReelStageJs() keeps returning a state that is neither `expected` nor 'failed'.

Common situations: Slow page/rendering exceeding the 20s default; Instagram UI redesign so the stage detector can't recognize the new editor; an unexpected non-failure dialog (consent, notification prompt) sitting on top; locale-specific DOM the inspector doesn't match.

Related errors


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