jackwener/OpenCLI · error · CommandExecutionError

Browser session required for instagram post

Error message

Browser session required for instagram post

What it means

requirePage throws this CommandExecutionError when the `page` argument passed into the instagram post command is null/undefined. All instagram UI-strategy commands require an active browser page (a logged-in browser session) because they drive the real instagram.com DOM. The library throws early instead of failing obscurely later during page.goto/evaluate.

Source

Thrown at clis/instagram/post.js:84

      const sharingVisible = /sharing/.test(visibleText);
      const shared = /post shared|your post has been shared|已分享|已发布/.test(visibleText)
        || /\\/p\\//.test(url);
      const failed = !shared && !sharingVisible && (
        /couldn['’]t be shared|could not be shared|failed to share|share failed|无法分享|分享失败/.test(visibleText)
        || (/something went wrong/.test(visibleText) && /try again/.test(visibleText))
      );
      const composerOpen = dialogs.some((dialog) =>
        !!dialog.querySelector('textarea, [contenteditable="true"], input[type="file"]')
        || /write a caption|add location|advanced settings|select from computer|crop|filters|adjustments|sharing/.test((dialog.textContent || '').toLowerCase())
      );
      const settled = !shared && !composerOpen && !/sharing/.test(visibleText);
      return { ok: shared, failed, settled, url: /\\/p\\//.test(url) ? url : '' };
    })()
  `;
}
function requirePage(page) {
    if (!page)
        throw new CommandExecutionError('Browser session required for instagram post');
    return page;
}
function validateMixedMediaItems(inputs) {
    if (!inputs.length) {
        throw new ArgumentError('Argument "media" is required.', 'Provide --media /path/to/file.jpg or --media /path/a.jpg,/path/b.mp4');
    }
    if (inputs.length > MAX_MEDIA_ITEMS) {
        throw new ArgumentError(`Too many media items: ${inputs.length}`, `Instagram carousel posts support at most ${MAX_MEDIA_ITEMS} items`);
    }
    const items = inputs.map((input) => {
        const resolved = path.resolve(String(input || '').trim());
        if (!resolved) {
            throw new ArgumentError('Media path cannot be empty');
        }
        if (!fs.existsSync(resolved)) {
            throw new ArgumentError(`Media file not found: ${resolved}`);
        }
        const ext = path.extname(resolved).toLowerCase();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open a browser session for instagram before posting (the command declares browser: true — supply the page it creates).
  2. Verify the page object is non-null before invoking the command in your own orchestration code.
  3. If a previous session was closed, restart the browser and obtain a fresh page handle instead of reusing the old variable.
  4. Check earlier pipeline steps for swallowed errors that left the page undefined.
  5. Ensure your environment actually supports the browser backend (installed/launchable browser) so a page can be created.

Example fix

// before
let page; // never assigned or session closed
await postToInstagram(page, { media: 'a.jpg' });
// after
const page = await openBrowserSession('instagram');
if (!page) throw new Error('Failed to open browser session');
await postToInstagram(page, { media: 'a.jpg' });
Defensive patterns

Strategy: type-guard

Validate before calling

// Before invoking the command
if (!page) throw new Error('Open a browser session for instagram first (command requires browser: true)');
if (typeof page.goto !== 'function' || typeof page.evaluate !== 'function') {
  throw new Error('page is not a valid browser page handle');
}

Type guard

function hasBrowserPage(page) {
  return !!page && typeof page === 'object' && typeof page.goto === 'function' && typeof page.evaluate === 'function' && typeof page.wait === 'function';
}

Try / catch

try {
  await cli.run('instagram post', { media: 'a.jpg' });
} catch (e) {
  if (e instanceof CommandExecutionError && e.message === 'Browser session required for instagram post') {
    await cli.run('open browser', { site: 'instagram' }); // re-establish session, then retry once
    await cli.run('instagram post', { media: 'a.jpg' });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the instagram post command without first starting/providing a browser session, or passing null/undefined for the page handle — e.g. running the command headless-without-browser, or after a browser session was closed and the stale page handle is null.

Common situations: Developers forget to run the browser/session-open command before posting; a script reuses a page variable from a session that already exited; running in an environment where browser:true commands were invoked without a browser backend; the previous step in a pipeline failed silently and returned no page.

Related errors


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