jackwener/OpenCLI · error · CommandExecutionError
Flomo API returned a malformed memo entry
Error message
Flomo API returned a malformed memo entry
What it means
normalizeMemo validates each entry in the `data` array returned by the Flomo /memo/updated/ API before mapping it into CLI output rows. This error is thrown when an entry is not a plain object — it is null/undefined, a primitive, or an Array — meaning the upstream API response shape differs from what this CLI expects. It indicates an API contract change or an unexpected response body rather than a problem with the caller's arguments.
Source
Thrown at clis/flomo/memos.js:127
.join(', ');
}
function normalizeImages(files) {
if (!Array.isArray(files)) return '';
return files
.map((file) => file?.thumbnail_url || file?.url || '')
.map((url) => String(url).trim())
.filter(Boolean)
.join(' | ');
}
function memoUrl(slug) {
return slug ? `https://${FLOMO_APP_DOMAIN}/mine/?memo_id=${encodeURIComponent(slug)}` : '';
}
function normalizeMemo(memo) {
if (!memo || typeof memo !== 'object' || Array.isArray(memo)) {
throw new CommandExecutionError('Flomo API returned a malformed memo entry');
}
const slug = String(memo.slug || memo.id || '').trim();
if (!slug) {
throw new CommandExecutionError('Flomo API returned a memo without slug/id');
}
return {
id: slug,
url: memoUrl(slug),
content: String(memo.content || '').trim(),
slug,
tags: normalizeTags(memo.tags),
images: normalizeImages(memo.files),
created_at: String(memo.created_at || ''),
updated_at: String(memo.updated_at || ''),
};
}
async function fetchFlomoJson(url, token) {View on GitHub (pinned to 49907e53dc)
Solutions
- Update the opencli package to the latest version so its Flomo parsing matches the current API schema.
- Retry after a short delay — a transient bad response (e.g. proxy injecting a page) usually does not persist.
- Check whether you are behind a proxy/firewall that rewrites responses to flomoapp.com and try a different network.
- Inspect the raw response by calling the signed URL manually to see what the API actually returns for memo entries.
Example fix
// before: CLI surfaces opaque CommandExecutionError
try {
rows = body.data.map(normalizeMemo);
} catch (e) {
console.error(e.message); // 'Flomo API returned a malformed memo entry'
}
// after: guard entries before mapping and report the offending index
const bad = body.data.findIndex((m) => !m || typeof m !== 'object' || Array.isArray(m));
if (bad !== -1) throw new Error(`memo at index ${bad} is not an object: ${JSON.stringify(body.data[bad])}`);
rows = body.data.map(normalizeMemo); Defensive patterns
Strategy: validation
Validate before calling
function validateMemosResponse(body) {
if (!body || typeof body !== 'object' || body.code !== 0) return 'bad envelope';
if (!Array.isArray(body.data)) return 'data is not an array';
const bad = body.data.findIndex((m) => !m || typeof m !== 'object' || Array.isArray(m));
return bad === -1 ? null : `memo at index ${bad} is not an object`;
}
// call before mapping: const problem = validateMemosResponse(body); Type guard
function isMemoEntry(m) {
return m !== null && typeof m === 'object' && !Array.isArray(m);
}
const safeRows = body.data.filter(isMemoEntry).map(normalizeMemo); Try / catch
try {
rows = body.data.map(normalizeMemo);
} catch (err) {
if (err.message.includes('malformed memo entry')) {
console.error('Flomo response schema changed; update opencli and retry.');
} else { throw err; }
} Prevention
- Keep the opencli package updated so parsing matches the current Flomo API schema.
- Validate the response envelope (code/data shape) before mapping entries.
- Log the raw response when normalization fails to ease diagnosing schema drift.
When it happens
Trigger: Calling `flomo memos` where body.data contains a null, undefined, string, number, or array element instead of a memo object; a Flomo API schema change that alters the memo list shape; a proxy/captive portal returning an unexpected JSON structure that still parses and has code 0 with non-object data items.
Common situations: Flomo changing their undocumented internal API response format; a middlebox or corporate proxy injecting its own JSON body; flomoapp.com rolling out a new app version (the CLI pins app_version 4.0) that reshapes memo entries; running an outdated CLI version against the current API.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Flomo API returned a memo without slug/id
- Bilibili creator comparison API returned malformed list data
- Bilibili creator comparison returned a malformed manuscript
- eastmoney convertible returned malformed diff data
- Gmail batch-view response had an unexpected shape
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1975f09c87ef4821.
Report an issue: GitHub.