{"record":{"id":"24bf589a7f88100e","repo":"jackwener/OpenCLI","slug":"failed-to-delete-draft-row-id","errorCode":null,"errorMessage":"Failed to delete draft ${row.id}","messagePattern":"Failed to delete draft (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/draft-delete.js","lineNumber":91,"sourceCode":"        const draftType = normalizeDraftType(kwargs.type);\n        const execute = kwargs.execute === true;\n        await ensureDraftDbPage(page);\n        const entries = await readDraftEntries(page, draftType);\n        const entry = findDraftEntry(entries, id);\n        if (!entry) throw draftNotFound(id, draftType, 'xiaohongshu/draft-delete');\n        const row = normalizeDraftRecord(entry.row, entry.key, draftType, 1);\n        if (!execute) {\n            return [{\n                status: 'dry-run',\n                id: row.id,\n                type: draftType,\n                message: 'Draft exists. Re-run with --execute to delete.',\n            }];\n        }\n        const storeName = STORE_NAME_MAP[draftType];\n        const result = unwrapBrowserResult(await page.evaluate(deleteDraftScript(storeName, entry.key)));\n        if (!result?.ok) {\n            throw new CommandExecutionError(result?.error || `Failed to delete draft ${row.id}`);\n        }\n        if (!result.deleted) {\n            throw new CommandExecutionError(`Draft ${row.id} still exists after delete`);\n        }\n        return [{\n            status: 'deleted',\n            id: row.id,\n            type: draftType,\n            message: 'Draft deleted.',\n        }];\n    },\n});\n","sourceCodeStart":73,"sourceCodeEnd":104,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/draft-delete.js#L73-L104","documentation":"Thrown by draft-delete.js when the in-page deleteDraftScript returns ok:false or no result, meaning the IndexedDB delete operation itself failed. The CLI falls back to a generic 'Failed to delete draft <id>' message when the script did not provide a more specific error.","triggerScenarios":"Calling the delete command with --execute when page.evaluate(deleteDraftScript(...)) returns undefined/null or { ok: false } — e.g. the IndexedDB transaction failed, the store is missing, or the browser page was closed or navigated mid-operation.","commonSituations":"Draft already deleted in the UI so the record/key is stale; browser page navigated away or crashed during the evaluate; XHS updated its database schema so STORE_NAME_MAP points at a nonexistent store.","solutions":["Re-run without --execute to confirm the draft still exists and get a fresh entry.key","Refresh/reconnect the browser page (ensureDraftDbPage) and retry the delete","Verify STORE_NAME_MAP for the chosen draftType matches the current XHS IndexedDB schema","If result.error is present in other code paths, inspect it; here the message hides it, so add logging or update the library"],"exampleFix":"// before\nconst result = unwrapBrowserResult(await page.evaluate(deleteDraftScript(storeName, entry.key)));\n// after\nif (!entry.key) throw new ArgumentError('Draft key missing; re-run lookup without --execute');\nconst result = unwrapBrowserResult(await page.evaluate(deleteDraftScript(storeName, entry.key)));","handlingStrategy":"try-catch","validationCode":"const entry = await lookupDraft(page, draftType, id); // dry-run: fetches entry.key\nif (!entry?.key) throw new Error(`Draft ${id} not found; nothing to delete`);","typeGuard":"function isDeleteResult(r) {\n  return r != null && typeof r === 'object' && r.ok === true && typeof r.deleted === 'boolean';\n}","tryCatchPattern":"try {\n  await draftDelete({ type: 'video', id, execute: true });\n} catch (e) {\n  if (/Failed to delete draft/.test(e.message)) {\n    console.error('Delete transaction failed — refresh the page/session and retry');\n  } else throw e;\n}","preventionTips":["Always run the dry-run lookup immediately before --execute so entry.key is fresh","Keep the target browser page alive and un-navigated during the command","Verify STORE_NAME_MAP matches the live IndexedDB schema after XHS updates","Handle the 'still exists after delete' follow-up error by re-fetching the key"],"tags":["indexeddb","cli","delete-failed"],"backgroundTag":"delete-operation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}