jackwener/OpenCLI · error · CommandExecutionError
Could not attach topic "${topic}": failed to accept suggesti
Error message
Could not attach topic "${topic}": failed to accept suggestion (${err && err.message || err}) What it means
addTopics types a '#' topic then presses Enter to accept XHS's topic suggestion dropdown. If the Enter keypress fails (browser API throws), the library wraps the underlying error in a CommandExecutionError so the topic attach step fails loudly instead of silently skipping the topic.
Source
Thrown at clis/xiaohongshu/publish.js:612
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`);
}
added.push(topic);
await page.wait({ time: 0.4 });
}
return added;
}
async function selectImageTextTab(page) {View on GitHub (pinned to 49907e53dc)
Solutions
- Check the inner err.message for the root cause (connection lost vs rejected key) and restore/reconnect the browser session, then retry publishing.
- Ensure the topic suggestion popup is actually open before Enter is pressed: slower typing / wait for the dropdown before calling addTopics.
- Retry the publish run; XHS UI timing is flaky and Enter acceptance often succeeds on a second attempt.
- If pressKey is systematically unavailable, verify the page wrapper implements pressKey (the code checks for its absence earlier at the 'pressKey is unavailable' branch).
Example fix
// before
await addTopics(page, topics); // throws on popup timing race
// after
for (const topic of topics) {
try {
await page.wait({ time: 1.0 });
await addTopics(page, [topic]);
} catch (e) {
if (!/failed to accept suggestion/.test(e.message)) throw e;
// retry once
await page.wait({ time: 2.0 });
await addTopics(page, [topic]);
}
} Defensive patterns
Strategy: retry
Validate before calling
if (typeof page.pressKey !== 'function') throw new Error('page.pressKey unavailable; cannot attach topics'); Type guard
function canPress(page) { return typeof page.pressKey === 'function'; } Try / catch
try { await addTopics(page, topics); }
catch (e) {
if (/failed to accept suggestion/.test(e.message)) {
await page.wait({ time: 2.0 });
await addTopics(page, topics); // retry once
} else throw e;
} Prevention
- Verify page.pressKey exists before starting the publish flow
- Wait for the topic suggestion dropdown before accepting
- Keep the browser session alive; check connection before long flows
When it happens
Trigger: page.pressKey('Enter') throws while a topic suggestion popup is open after typing "#<topic>" in the publish editor, e.g. browser connection dropped, page navigated, or the browser driver rejected the key event.
Common situations: Browser session crashed or disconnected mid-flow; suggestion popup stole focus or closed before Enter landed; remote browser (CDP/webdriver) rate-limits or errors on key events; running in a headless driver whose pressKey implementation is missing or throws.
Related errors
- 当前浏览器适配器不支持文件注入
- Mercury appears to have an existing expense review open; ref
- Could not find the Mercury Submit expense or New expense but
- Upwork job-detail store had an unexpected job shape; expecte
- xiaohongshu collection interceptor returned malformed captur
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/91c3532341aa6764.
Report an issue: GitHub.