jackwener/OpenCLI · error · CommandExecutionError

Could not attach topic "${topic}": page.pressKey is unavaila

Error message

Could not attach topic "${topic}": page.pressKey is unavailable

What it means

CommandExecutionError guard in addTopics: after typing '#<topic>' the flow presses Enter to accept XHS's auto-highlighted first suggestion, but page.pressKey is not a function on the current page object. Since there is no reliable alternative wired into every wrapper, it throws with per-topic context.

Source

Thrown at clis/xiaohongshu/publish.js:606

        // `execCommand` path, otherwise XHS's editor doesn't fire its keyup
        // listener and no dropdown appears.
        if (typeof page.insertText !== 'function') {
            throw new CommandExecutionError(`Could not attach topic "${topic}": page.insertText is unavailable`);
        }
        try {
            await page.insertText(`#${topic}`);
        }
        catch {
            throw new CommandExecutionError(`Could not attach topic "${topic}": failed to type inline topic query`);
        }
        await page.wait({ time: 1.2 }); // Let the suggestion dropdown render.
        // The suggestion dropdown lives inside the editor's closed shadow root,
        // so light-DOM queries cannot enumerate its items. XHS auto-highlights
        // the first matching suggestion as soon as the query is typed, so
        // pressing Enter accepts it directly. `page.nativeClick` would also
        // work but is not always wired up in the browser-bridge wrapper.
        if (typeof page.pressKey !== 'function') {
            throw new CommandExecutionError(`Could not attach topic "${topic}": page.pressKey is unavailable`);
        }
        try {
            await page.pressKey('Enter');
        }
        catch (err) {
            throw new CommandExecutionError(`Could not attach topic "${topic}": failed to accept suggestion (${err && err.message || err})`);
        }
        await page.wait({ time: 0.8 });
        // Verify the topic chip actually rendered. The chip itself lives in a
        // closed shadow root so we cannot count `<a>` elements, but XHS exposes
        // a stable "#<topic>[话题]" marker in the body editor's innerText once
        // the suggestion is accepted. Require the scoped marker count to
        // increase so an existing marker elsewhere cannot satisfy the write
        // postcondition.
        const afterMarkerCount = Number(unwrapBrowserResult(await page.evaluate(topicMarkerCountScript(topic, bodySelectors)))) || 0;
        if (afterMarkerCount <= beforeMarkerCount) {
            throw new CommandExecutionError(`Could not attach topic "${topic}": no real topic entity appeared after selection`);
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Upgrade the CLI/browser bridge so page.pressKey is available.
  2. Use the officially supported browser wrapper rather than a custom page object.
  3. Publish without topics (remove the topics option) if your bridge cannot support them.
  4. Pre-flight check: assert typeof page.pressKey === 'function' before a topics publish.

Example fix

// before
await xhs.publish({ topics: ['travel'], ... }); // bridge lacks pressKey
// after
if (typeof page.pressKey !== 'function') delete opts.topics; // degrade gracefully
await xhs.publish(opts);
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-flight before a topics publish
if (opts.topics && typeof page.pressKey !== 'function') {
  throw new Error('Bridge lacks pressKey; publish without topics or upgrade');
}

Type guard

function supportsKeyboard(page) {
  return typeof page.pressKey === 'function';
}

Try / catch

try {
  await xhs.publish(opts);
} catch (err) {
  if (err.message.includes('page.pressKey is unavailable')) {
    console.error('Use a bridge with pressKey support or omit topics');
  } else throw err;
}

Prevention

When it happens

Trigger: Browser-bridge wrapper without a pressKey implementation; older/patched driver versions; custom page shims exposing only legacy keyboard APIs.

Common situations: Using an alternative automation backend or outdated opencli bridge; environments where keyboard event dispatch is stubbed; running with a wrapper built for a different CLI version.

Related errors


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