jackwener/OpenCLI · error · CommandExecutionError

Edit click failed

Error message

Edit click failed

What it means

In history-rename, after navigating to /chat/history, an in-page script finds the chat row by href, walks up to a container, locates svg[name='Edit'], and clicks its nearest button-like ancestor. Any failure (row not found, no Edit svg, no clickable ancestor) returns {ok:false,reason}, and the command throws CommandExecutionError(reason || 'Edit click failed').

Source

Thrown at clis/kimi/audit-extras.js:238

        // Navigate to history page
        await page.goto(`${KIMI_URL}chat/history`);
        await page.wait(2);
        // Find the row with href containing the chat id, then click its Edit svg
        const clickRes = await page.evaluate(`(() => {
      ${IS_VISIBLE_JS}
      const row = Array.from(document.querySelectorAll('a[href*="/chat/' + ${JSON.stringify(id)} + '"]')).find(isVisible);
      if (!row) return { ok: false, reason: 'Chat row not found in history.' };
      // The Edit svg is in a sibling or descendant.
      let container = row.parentElement || row;
      for (let i = 0; i < 4 && container.parentElement; i++) container = container.parentElement;
      const editSvg = container.querySelector('svg[name="Edit"]');
      if (!editSvg) return { ok: false, reason: 'Edit svg not found near chat row.' };
      let editBtn = editSvg;
      for (let i = 0; i < 5 && editBtn.parentElement; i++) { editBtn = editBtn.parentElement; if (editBtn.getAttribute('role') === 'button' || editBtn.tagName === 'BUTTON') break; }
      editBtn.click();
      return { ok: true };
    })()`);
        if (!clickRes?.ok) throw new CommandExecutionError(clickRes?.reason || 'Edit click failed', '');
        await page.wait(0.5);
        // Fill the inline input + submit via Enter
        const fillRes = await page.evaluate(`(() => {
      ${IS_VISIBLE_JS}
      const inputs = Array.from(document.querySelectorAll('input[type="text"], input:not([type])')).filter(isVisible);
      const input = inputs[inputs.length - 1];
      if (!input) return { ok: false, reason: 'No input mounted after clicking Edit.' };
      const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
      setter.call(input, ${JSON.stringify(newTitle)});
      input.dispatchEvent(new Event('input', { bubbles: true }));
      input.dispatchEvent(new Event('change', { bubbles: true }));
      input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
      return { ok: true };
    })()`);
        if (!fillRes?.ok) throw new CommandExecutionError(fillRes?.reason || 'Rename input fill failed', '');
        await page.wait(1);
        const verified = await page.evaluate(`(() => {
      const row = Array.from(document.querySelectorAll('a[href*="/chat/' + ${JSON.stringify(id)} + '"]'))

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the chat-id exists: open kimi.com/chat/<id> in a browser — if 404, the conversation is gone
  2. Increase the initial wait / retry after the history page finishes loading (rows may render late)
  3. In a browser, check whether the row still exposes svg[name='Edit']; if Kimi moved it into a dropdown menu, update the script's selector logic
  4. Re-run once — transient render timing is the most common cause

Example fix

// before
await page.wait(2);
const clickRes = await page.evaluate(editClickScript(id));
// after
await page.wait(4);
let clickRes = await page.evaluate(editClickScript(id));
if (!clickRes?.ok) { await page.wait(2); clickRes = await page.evaluate(editClickScript(id)); }
Defensive patterns

Strategy: retry

Validate before calling

const rowExists = await page.evaluate(`!!document.querySelector("a[href*='/chat/${id}']")`);
if (!rowExists) throw new Error(`chat ${id} not in history — verify the id or wait for the list to load`);

Type guard

function isClickResult(res) { return res != null && typeof res === 'object' && typeof res.ok === 'boolean'; }

Try / catch

try {
  await runCli('kimi history-edit', { 'chat-id': id, 'new-title': t, yes: true });
} catch (e) {
  if (/Edit click failed|Chat row not found|Edit svg not found/i.test(e.message)) {
    await sleep(3000);
    return runCli('kimi history-edit', { 'chat-id': id, 'new-title': t, yes: true });
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `kimi history-edit <id> <title> --yes` when: the chat id doesn't exist or was deleted (row not found), the history list hasn't rendered within the 2s wait, Kimi changed svg name='Edit' to another icon name, or the row exists but its Edit control only appears on hover (not visible to the script).

Common situations: Renaming an old conversation that was deleted on another device; slow load so rows aren't in the DOM yet; Kimi UI update moving the Edit action into a '...' menu instead of an inline svg; chat id typo so no anchor href matches.

Related errors


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