jackwener/OpenCLI · error · CommandExecutionError

Instagram fallback file injection failed

Error message

Instagram fallback file injection failed

What it means

injectImageViaBrowser is the fallback path that injects files into the composer's file input via in-page JS when page.setFileInput is unavailable. If the injected script returns ok:false (or returns nothing at all), the library surfaces the script's error string, defaulting to this message. It indicates the browser-side DOM injection could not complete.

Source

Thrown at clis/instagram/post.js:549

          const bytes = new Uint8Array(binary.length);
          for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
          const blob = new Blob([bytes], { type: img.type });
          const file = new File([blob], img.name, { type: img.type });
          dt.items.add(file);
        }
        Object.defineProperty(input, 'files', { value: dt.files, configurable: true });
        input.dispatchEvent(new Event('change', { bubbles: true }));
        input.dispatchEvent(new Event('input', { bubbles: true }));
        cleanup();
        return { ok: true, count: dt.files.length };
      } catch (error) {
        cleanup();
        return { ok: false, error: String(error) };
      }
    })()
  `);
    if (!result?.ok) {
        throw new CommandExecutionError(result?.error || 'Instagram fallback file injection failed');
    }
}
async function dispatchUploadEvents(page, selector) {
    await page.evaluate(`
    (() => {
      const input = document.querySelector(${JSON.stringify(selector)});
      if (!(input instanceof HTMLInputElement)) return { ok: false };
      input.dispatchEvent(new Event('input', { bubbles: true }));
      input.dispatchEvent(new Event('change', { bubbles: true }));
      return { ok: true };
    })()
  `);
}
export function buildInspectUploadStageJs() {
    return `
    (() => {
      const isVisible = (el) => {
        if (!(el instanceof HTMLElement)) return false;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run with Browser Bridge mode so page.setFileInput is available and the fallback is never needed
  2. Re-resolve the upload selector (resolveUploadSelectors) before retrying, the old one may be stale
  3. Screenshot the page to check whether the composer is still open and the input still exists
  4. Retry the post; transient SPA re-renders often break one injection attempt but not the next

Example fix

// before
await uploadMedia(page, mediaItems, selector);
// after
try {
  await uploadMedia(page, mediaItems, selector);
} catch (e) {
  if (String(e.message).includes('fallback file injection')) {
    const fresh = await resolveUploadSelectors(page, mediaItems);
    await uploadMedia(page, mediaItems, fresh[0]);
  } else throw e;
}
Defensive patterns

Strategy: fallback

Validate before calling

if (typeof page.setFileInput !== 'function') {
  console.warn('setFileInput unavailable; browser-injection fallback will be used');
}

Try / catch

try {
  await uploadMedia(page, mediaItems, selector);
} catch (e) {
  if (String(e.message).includes('fallback file injection failed')) {
    const selectors = await resolveUploadSelectors(page, mediaItems);
    await uploadMedia(page, mediaItems, selectors[0]);
  } else throw e;
}

Prevention

When it happens

Trigger: uploadMedia falls back to injectImageViaBrowser after a setFileInput failure, and the in-page script hits an exception or fails to set input.files, returning { ok:false, error } — the thrown message is result.error or the default fallback string.

Common situations: Browser mode without setFileInput support (non-Browser-Bridge driver), page navigated away mid-upload, DOMPurify/React intercepting synthetic file assignment, or selector stale after composer re-render.

Related errors


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