jackwener/OpenCLI · error · CommandExecutionError

Claude composer is not available on the current page.

Error message

Claude composer is not available on the current page.

What it means

opencli's Claude commands drive the Claude web UI via a browser page. Before sending a prompt it verifies the user is logged in and that the message composer input exists on the page. If the composer element is not found (state.hasComposer is false), ensureClaudeComposer throws this CommandExecutionError because no command can proceed without it.

Source

Thrown at clis/claude/utils.js:64

            title: document.title,
            hasComposer: !!composer,
            isLoggedIn: !!userMenu,
        };
    })()`);
}

export async function ensureClaudeLogin(page, message = 'Claude requires a logged-in browser session.') {
    const state = await getPageState(page);
    if (!state.isLoggedIn) {
        throw new AuthRequiredError(CLAUDE_DOMAIN, message);
    }
    return state;
}

export async function ensureClaudeComposer(page, message = 'Claude composer is not available on the current page.') {
    const state = await ensureClaudeLogin(page, message);
    if (!state.hasComposer) {
        throw new CommandExecutionError(message);
    }
    return state;
}

export function requireNonEmptyPrompt(prompt, commandName) {
    const text = String(prompt ?? '').trim();
    if (!text) {
        throw new ArgumentError(
            `${commandName} prompt cannot be empty`,
            `Example: opencli ${commandName} "hello"`,
        );
    }
    return text;
}

export function requirePositiveInt(value, flagLabel, hint) {
    if (!Number.isInteger(value) || value < 1) {
        throw new ArgumentError(`${flagLabel} must be a positive integer`, hint);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run `opencli claude login` (or the auth flow) to establish a valid session, then retry
  2. Open the page in a normal browser and confirm the composer is visible (complete any login/bot challenge)
  3. Update opencli to the latest version so composer selectors match the current Claude UI
  4. Retry later if Claude is showing an outage/interstitial page

Example fix

// before
await askCommand(page, { prompt: 'hi' }); // throws if session stale
// after
await claudeLogin(page); // refresh session first
await askCommand(page, { prompt: 'hi' });
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling: check session state via the same helper
const state = await ensureClaudeLogin(page);
if (!state.hasComposer) {
  throw new Error('Composer unavailable; run `opencli claude login` first');
}

Type guard

function hasComposerState(state) {
  return typeof state === 'object' && state !== null && state.hasComposer === true;
}

Try / catch

try {
  await askCommand(page, { prompt });
} catch (e) {
  if (e instanceof CommandExecutionError && /composer is not available/.test(e.message)) {
    await claudeLogin(page); // refresh session, then retry once
    await askCommand(page, { prompt });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling opencli claude ask/new/send when the loaded claude.ai page has no visible message composer: not logged in, a bot-check or interstitial page, session expired mid-flow, or the composer selector no longer matches after a Claude UI update.

Common situations: Expired browser session/cookies, running headless against a Cloudflare challenge, Claude product UI redesign changing DOM structure, landing on a page other than the chat surface.

Related errors


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