{"record":{"id":"572fe8158ba8f2af","repo":"jackwener/OpenCLI","slug":"instagram-reel-expected-editor-did-not-appear","errorCode":null,"errorMessage":"Instagram reel ${expected} editor did not appear","messagePattern":"Instagram reel (.+?) editor did not appear","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/instagram/reel.js","lineNumber":283,"sourceCode":"      if (/crop|select crop|open media gallery/.test(lower) && hasVisibleButton(['next'])) {\n        return { state: 'crop', detail: text };\n      }\n      return { state: 'pending', detail: text };\n    })()\n  `;\n}\nasync function waitForReelStage(page, expected, maxWaitSeconds = 20) {\n    for (let attempt = 0; attempt < maxWaitSeconds * 2; attempt += 1) {\n        const result = await page.evaluate(buildInspectReelStageJs());\n        if (result?.state === expected)\n            return;\n        if (result?.state === 'failed') {\n            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');\n        }\n        if (attempt < maxWaitSeconds * 2 - 1)\n            await page.wait({ time: 0.5 });\n    }\n    throw new CommandExecutionError(`Instagram reel ${expected} editor did not appear`);\n}\nasync function focusCaptionEditor(page) {\n    const result = await page.evaluate(`\n    (() => {\n      const isVisible = (el) => {\n        if (!(el instanceof HTMLElement)) return false;\n        const style = window.getComputedStyle(el);\n        const rect = el.getBoundingClientRect();\n        return style.display !== 'none'\n          && style.visibility !== 'hidden'\n          && rect.width > 0\n          && rect.height > 0;\n      };\n      const dialogs = Array.from(document.querySelectorAll('[role=\"dialog\"]')).filter((el) => isVisible(el));\n      for (const dialog of dialogs) {\n        const textarea = dialog.querySelector('[aria-label=\"Write a caption...\"], textarea');\n        if (textarea instanceof HTMLTextAreaElement && isVisible(textarea)) {\n          textarea.focus();","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/reel.js#L265-L301","documentation":"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.","triggerScenarios":"The for-loop in waitForReelStage exhausts all maxWaitSeconds*2 attempts while buildInspectReelStageJs() keeps returning a state that is neither `expected` nor 'failed'.","commonSituations":"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.","solutions":["Capture a screenshot at timeout (add one like waitForVideoPreview does) to see the actual page state.","Increase the maxWaitSeconds argument for slower environments.","Broaden buildInspectReelStageJs detection to match the current editor DOM/labels.","Dismiss or handle any blocking dialogs (consent/notification prompts) before polling.","Retry the flow; transient render delays often resolve on a second run."],"exampleFix":"// before\nawait waitForReelStage(page, 'share'); // default 20s\n// after\nawait waitForReelStage(page, 'share', 60); // give slow loads time to render","handlingStrategy":"retry","validationCode":"// Dismiss known blocking prompts before waiting for the editor stage\nawait clickActionMaybe(page, ['Allow all cookies', 'Allow', 'Not now', 'Next']);","typeGuard":"function isExpectedStage(r, expected) {\n  return !!r && typeof r === 'object' &&\n    (r.state === expected || r.state === 'failed') &&\n    (r.detail === undefined || typeof r.detail === 'string');\n}","tryCatchPattern":"try {\n  await waitForReelStage(page, expected, 20);\n} catch (err) {\n  if (String(err.message).includes('editor did not appear')) {\n    await page.screenshot({ path: '/tmp/ig_stage_timeout.png' });\n    // retry once after handling whatever the screenshot shows\n    await waitForReelStage(page, expected, 60);\n  } else throw err;\n}","preventionTips":["Add a timeout screenshot (mirroring waitForVideoPreview) to diagnose page state","Raise maxWaitSeconds on slow environments or heavy pages","Keep buildInspectReelStageJs selectors current with Instagram's editor DOM","Dismiss consent/notification dialogs before polling for the stage"],"tags":["instagram","timeout","editor","puppeteer","automation"],"backgroundTag":"ui-stage-timeout","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}