jackwener/OpenCLI · error · CommandExecutionError
Twitter bookmarks resume file ${filePath} is missing in-memo
Error message
Twitter bookmarks resume file ${filePath} is missing in-memory tweets What it means
In-memory mode (no --output-file) stores the fetched tweets inside the resume file itself. If expected.outputFile is null but the resume file lacks a `tweets` array, readResumeFile throws this CommandExecutionError because there is no archive and no stored tweets to continue from.
Source
Thrown at clis/twitter/bookmarks.js:130
catch (error) {
throw new CommandExecutionError(`Could not parse Twitter bookmarks resume file ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
}
const count = parsed?.count;
const cursor = parsed?.cursor == null ? null : String(parsed.cursor);
const outputFile = parsed?.outputFile ? path.resolve(String(parsed.outputFile)) : null;
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)
|| !Number.isInteger(count) || count < 0
|| (parsed.cursor != null && typeof parsed.cursor !== 'string')
|| (cursor !== null && !cursor.trim())) {
throw new CommandExecutionError(`Twitter bookmarks resume file ${filePath} has an invalid shape`);
}
if (expected) {
if (parsed.source !== expected.source)
throw new ArgumentError(`Resume file source mismatch: expected ${expected.source}, found ${parsed.source || 'unknown'}`);
if (outputFile !== expected.outputFile)
throw new ArgumentError(`Resume file output mismatch: expected ${expected.outputFile || 'in-memory mode'}, found ${outputFile || 'in-memory mode'}`);
if (!expected.outputFile && !Array.isArray(parsed.tweets))
throw new CommandExecutionError(`Twitter bookmarks resume file ${filePath} is missing in-memory tweets`);
if (!expected.outputFile && parsed.tweets.length !== count)
throw new CommandExecutionError(`Twitter bookmarks resume file ${filePath} count does not match its in-memory tweets`);
if (parsed.complete)
throw new CommandExecutionError(`Twitter bookmarks resume file ${filePath} is already marked complete`);
}
return {
cursor,
count,
tweets: Array.isArray(parsed.tweets) ? parsed.tweets : [],
complete: Boolean(parsed.complete),
source: parsed.source || null,
outputFile,
updatedAt: parsed.updatedAt || null,
};
}
// Keep this in sync with twitter/likes; wording is command-specific, so the
// atomic tmp-write/rename cleanup sequence intentionally remains local.View on GitHub (pinned to 49907e53dc)
Solutions
- Delete the resume file and restart the --all sync (in-memory state cannot be reconstructed without tweets).
- Re-run with --output-file --resume-file so partial data lives in the JSONL archive instead.
- Restore `tweets` from a backup if the original array is available.
Example fix
// before: resume.json = {"count": 5, "cursor": "X", "source": "bookmarks"} (no tweets)
// after: add back or restart
cli twitter bookmarks --all --resume-file ./b.json --output-file ./archive.jsonl Defensive patterns
Strategy: validation
Validate before calling
const parsed = JSON.parse(fs.readFileSync(resumeFile, 'utf8'));
if (!parsed.outputFile && !Array.isArray(parsed.tweets)) {
// in-memory resume state unusable: start fresh or switch to archive mode
fs.rmSync(resumeFile, { force: true });
} Type guard
function hasInMemoryTweets(v) {
return typeof v === 'object' && v !== null && Array.isArray(v.tweets);
} Try / catch
try {
await run(args);
} catch (e) {
if (String(e.message).includes('is missing in-memory tweets')) {
fs.rmSync(resumeFile, { force: true });
await run(args); // restart clean
} else throw e;
} Prevention
- Do not strip the `tweets` array from in-memory resume files.
- For long syncs use --output-file --resume-file so data lives in the archive.
- Never truncate the resume file to save space.
- Regenerate rather than repair untrusted resume files.
When it happens
Trigger: Resuming an in-memory --all run whose resume file has `tweets` removed or renamed (manual edit), or resuming with an outputFile-crafted file while running without --output-file.
Common situations: Cleaning up the resume file to shrink it and deleting `tweets`; a schema change between library versions; mixing files produced with different flags.
Related errors
- Could not parse Twitter bookmarks resume file ${filePath}: $
- Twitter bookmarks resume file ${filePath} has an invalid sha
- Twitter bookmarks resume file ${filePath} count does not mat
- Twitter bookmarks resume file ${filePath} is already marked
- Twitter likes resume file ${filePath} count does not match i
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/cd2af48a4936ee3a.
Report an issue: GitHub.