{"record":{"id":"2385ba851012abbb","repo":"jackwener/OpenCLI","slug":"failed-to-read-drafttype-drafts","errorCode":null,"errorMessage":"Failed to read ${draftType} drafts","messagePattern":"Failed to read (.+?) drafts","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/draft-utils.js","lineNumber":129,"sourceCode":"          req.onerror = () => reject(req.error || new Error('failed to read draft keys'));\n        });\n        db.close();\n        return {\n          ok: true,\n          entries: allRows.map((row, index) => ({ key: allKeys[index] ?? index, row })),\n        };\n      } catch (error) {\n        return { ok: false, error: String(error && error.message || error) };\n      }\n    })()\n  `;\n}\n\nexport async function readDraftEntries(page, draftType) {\n    const storeName = STORE_NAME_MAP[draftType];\n    const payload = unwrapBrowserResult(await page.evaluate(draftReadScript(storeName)));\n    if (!payload?.ok) {\n        throw new CommandExecutionError(payload?.error || `Failed to read ${draftType} drafts`);\n    }\n    if (!Array.isArray(payload.entries)) {\n        throw new CommandExecutionError(`Malformed ${draftType} draft payload`);\n    }\n    return payload.entries;\n}\n\nexport function draftNotFound(id, draftType, command) {\n    return new EmptyResultError(\n        command,\n        `Draft ${id} was not found in ${draftType} drafts. Run opencli xiaohongshu drafts --type ${draftType} to list current ids.`,\n    );\n}\n","sourceCodeStart":111,"sourceCodeEnd":143,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/draft-utils.js#L111-L143","documentation":"readDraftEntries reads a Xiaohongshu draft store from the page via an in-page script. It throws CommandExecutionError when the in-page script returns a payload without ok:true and without its own error message, using this generic fallback. This indicates the browser-side read itself failed.","triggerScenarios":"page.evaluate(draftReadScript(storeName)) returns a payload where payload.ok is falsy and payload.error is undefined/empty; also when unwrapBrowserResult returns null/undefined so payload?.ok is falsy.","commonSituations":"The draft store name is not in STORE_NAME_MAP (wrong draftType), the page is not logged in or navigated to the creator center, the in-page script threw and was swallowed, or the SPA hasn't hydrated the IndexedDB/local store yet.","solutions":["Verify draftType is one of the keys supported by STORE_NAME_MAP","Ensure the page is logged in and fully loaded on the drafts/creator page before calling","Reload the page and retry the drafts command","Log payload from a manual page.evaluate of draftReadScript(storeName) to see the underlying failure","Check for site DOM/SPA changes that break the in-page draft read script"],"exampleFix":"// before\nconst entries = await readDraftEntries(page, 'favorites');\n// after\nif (!STORE_NAME_MAP[draftType]) throw new ArgumentError(`Unknown draftType: ${draftType}`);\nawait page.wait({ time: 2 }); // allow SPA/store hydration\nconst entries = await readDraftEntries(page, 'favorites');","handlingStrategy":"try-catch","validationCode":"if (!STORE_NAME_MAP[draftType]) throw new Error(`Unknown draftType: ${draftType}`);","typeGuard":"function isDraftPayload(p) { return !!p && typeof p === 'object' && p.ok === true; }","tryCatchPattern":"try {\n  const entries = await readDraftEntries(page, draftType);\n} catch (err) {\n  if (err instanceof CommandExecutionError && /Failed to read .* drafts/.test(err.message)) {\n    await page.reload();\n    await page.wait({ time: 3 });\n    // retry once or surface a clear 'not logged in / page not ready' hint\n  } else throw err;\n}","preventionTips":["Validate draftType against STORE_NAME_MAP before calling","Ensure login state and correct page URL before reading drafts","Wait for SPA hydration before evaluating","Wrap in-page reads with try/catch that returns { ok:false, error } so real causes surface"],"tags":["browser-automation","drafts","spa"],"backgroundTag":"browser-evaluate-payload-not-ok","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}