jackwener/OpenCLI · error · CommandExecutionError

Failed to read ${draftType} drafts

Error message

Failed to read ${draftType} drafts

What it means

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.

Source

Thrown at clis/xiaohongshu/draft-utils.js:129

          req.onerror = () => reject(req.error || new Error('failed to read draft keys'));
        });
        db.close();
        return {
          ok: true,
          entries: allRows.map((row, index) => ({ key: allKeys[index] ?? index, row })),
        };
      } catch (error) {
        return { ok: false, error: String(error && error.message || error) };
      }
    })()
  `;
}

export async function readDraftEntries(page, draftType) {
    const storeName = STORE_NAME_MAP[draftType];
    const payload = unwrapBrowserResult(await page.evaluate(draftReadScript(storeName)));
    if (!payload?.ok) {
        throw new CommandExecutionError(payload?.error || `Failed to read ${draftType} drafts`);
    }
    if (!Array.isArray(payload.entries)) {
        throw new CommandExecutionError(`Malformed ${draftType} draft payload`);
    }
    return payload.entries;
}

export function draftNotFound(id, draftType, command) {
    return new EmptyResultError(
        command,
        `Draft ${id} was not found in ${draftType} drafts. Run opencli xiaohongshu drafts --type ${draftType} to list current ids.`,
    );
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify draftType is one of the keys supported by STORE_NAME_MAP
  2. Ensure the page is logged in and fully loaded on the drafts/creator page before calling
  3. Reload the page and retry the drafts command
  4. Log payload from a manual page.evaluate of draftReadScript(storeName) to see the underlying failure
  5. Check for site DOM/SPA changes that break the in-page draft read script

Example fix

// before
const entries = await readDraftEntries(page, 'favorites');
// after
if (!STORE_NAME_MAP[draftType]) throw new ArgumentError(`Unknown draftType: ${draftType}`);
await page.wait({ time: 2 }); // allow SPA/store hydration
const entries = await readDraftEntries(page, 'favorites');
Defensive patterns

Strategy: try-catch

Validate before calling

if (!STORE_NAME_MAP[draftType]) throw new Error(`Unknown draftType: ${draftType}`);

Type guard

function isDraftPayload(p) { return !!p && typeof p === 'object' && p.ok === true; }

Try / catch

try {
  const entries = await readDraftEntries(page, draftType);
} catch (err) {
  if (err instanceof CommandExecutionError && /Failed to read .* drafts/.test(err.message)) {
    await page.reload();
    await page.wait({ time: 3 });
    // retry once or surface a clear 'not logged in / page not ready' hint
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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