{"record":{"id":"03b1849b63ec90a7","repo":"jackwener/OpenCLI","slug":"xiaohongshu-delete-note-failed-to-locate-note-row","errorCode":null,"errorMessage":"xiaohongshu/delete-note: failed to locate note row","messagePattern":"xiaohongshu/delete-note: failed to locate note row","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/delete-note.js","lineNumber":203,"sourceCode":"    `)), 'published-tab');\n            if (!tabClicked) {\n                throw new CommandExecutionError('xiaohongshu/delete-note: 已发布 tab not found on note-manager; xhs creator UI may have changed.');\n            }\n            await page.wait({ time: ROW_SETTLE_MS / 1000 });\n            // Step 2: locate the .note row whose data-impression JSON carries the\n            // exact `noteId` field. Dry-run stops here; execute clicks delete.\n            // Substring matching on the raw attribute would risk matching unrelated\n            // fields whose values happen to share the noteId prefix, so parse the JSON\n            // and compare `noteTarget.value.noteId` explicitly.\n            const initResult = requireActionResult(unwrapEvaluateResult(await page.evaluate(buildLocateAndMaybeDeleteScript(noteId, execute))), 'locate-note');\n            if (!initResult?.ok) {\n                if (initResult?.kind === 'not_found') {\n                    throw new EmptyResultError('xiaohongshu/delete-note', `Note ${noteId} not visible in the 已发布 tab. Verify the note belongs to the logged-in account and has cleared review (审核中 / 未通过 rows have no web delete entry).`);\n                }\n                if (initResult?.kind === 'no_delete_action') {\n                    throw new CommandExecutionError(`xiaohongshu/delete-note: note ${noteId} row found but no delete action visible; xhs creator UI may have changed.`);\n                }\n                throw new CommandExecutionError('xiaohongshu/delete-note: failed to locate note row');\n            }\n            if (!execute) {\n                return [{ status: 'dry-run', note_id: noteId, message: 'Target note row and delete action verified. Re-run with --execute to delete.' }];\n            }\n            await page.wait({ time: MODAL_SETTLE_MS / 1000 });\n            // Step 3: click \"确定\" in the `.d-modal-footer` confirmation modal.\n            const confirmResult = requireActionResult(unwrapEvaluateResult(await page.evaluate(`\n      () => {\n        const isVisible = (el) => !!el && el.offsetParent !== null;\n        const footer = Array.from(document.querySelectorAll('.d-modal-footer')).find(isVisible);\n        if (!footer) return { ok: false, kind: 'no_modal' };\n        const buttons = Array.from(footer.querySelectorAll('button, [role=\"button\"]')).filter(isVisible);\n        const confirmBtn = buttons.find((b) => (b.innerText || b.textContent || '').trim() === '确定');\n        if (!confirmBtn) return { ok: false, kind: 'no_confirm', labels: buttons.map(b => (b.innerText || '').trim()) };\n        confirmBtn.click();\n        return { ok: true };\n      }\n    `)), 'confirm-modal');","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/delete-note.js#L185-L221","documentation":"Generic fallback for the locate step: the injected script returned { ok: false } with a kind that was neither 'not_found' nor 'no_delete_action' (or the result shape was unexpected beyond the boolean check). The CLI throws this CommandExecutionError because it cannot classify the locate failure.","triggerScenarios":"The injected locate script returned an unexpected failure kind (e.g. an exception path inside the page context, a new kind added by a mismatched script/result version); the page was navigated or the execution context destroyed mid-evaluate; partial rendering left rows in an inconsistent state.","commonSituations":"Version skew between the injected script builder and the result parser after a partial library update; XHS JS throwing during row scan so the script exits early with an unclassified status; SPA re-render racing the evaluate call.","solutions":["Re-run the command; transient rendering races often resolve on retry","Ensure the opencli package (and clis/xiaohongshu files) are all the same version — no partial upgrades","Load the note-manager page in the browser first to confirm it renders normally before running the command","If reproducible, file/inspect with the actual initResult payload to identify the unhandled kind and update the classification logic"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await cli('xiaohongshu', 'delete-note', { note: noteId });\n} catch (err) {\n  if (err instanceof CommandExecutionError && err.message.includes('failed to locate note row')) {\n    await sleep(3000); // transient render/execution race — retry once\n    return cli('xiaohongshu', 'delete-note', { note: noteId });\n  }\n  throw err;\n}","preventionTips":["Retry transient locate failures once before escalating","Keep all related packages on one version to avoid script/result kind mismatches","Load and settle the note-manager page before running the delete command","Capture the raw initResult payload when debugging to identify unclassified failure kinds"],"tags":["browser-automation","ui-automation","unclassified"],"backgroundTag":"ui-selector-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}