jackwener/OpenCLI · error · CommandExecutionError
Flomo API returned malformed memo data
Error message
Flomo API returned malformed memo data
What it means
clis/flomo/memos.js throws this CommandExecutionError after a Flomo API response arrives but its `data` field is not an array. The memos command expects the envelope `{ data: [...] }`; any other shape means the API contract changed or the response is not memo data. It guards downstream `body.data.map(normalizeMemo)` from crashing on a non-array.
Source
Thrown at clis/flomo/memos.js:212
func: async (page, kwargs) => {
const limit = parsePositiveIntArg(kwargs.limit, 'limit', 20, MAX_LIMIT);
const since = parseSinceArg(kwargs.since);
const slug = parseSlugArg(kwargs.slug);
await page.wait(3).catch(() => {});
const token = await readAccessToken(page);
const body = await fetchFlomoJson(buildSignedUrl(limit, since, slug), token);
if (!body || typeof body !== 'object' || Array.isArray(body)) {
throw new CommandExecutionError('Flomo API returned a malformed response');
}
if (body.code !== 0) {
const message = body.message || `Flomo API error code ${body.code}`;
if (isAuthFailureMessage(message)) {
throw new AuthRequiredError(FLOMO_API_DOMAIN, message);
}
throw new CommandExecutionError(message);
}
if (!Array.isArray(body.data)) {
throw new CommandExecutionError('Flomo API returned malformed memo data');
}
if (body.data.length === 0) {
throw new EmptyResultError('flomo memos', 'No Flomo memos matched the requested filters.');
}
return body.data.map(normalizeMemo);
},
});
export const __test__ = {
buildSignedUrl,
command,
normalizeMemo,
parsePositiveIntArg,
parseSinceArg,
parseSlugArg,
};
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command with a valid, fresh Flomo session/auth to rule out a redirected login response
- Inspect the raw response body (log `body` before validation) to see what shape actually arrived
- Update opencli/flomo CLI to a version matching the current Flomo API response format
- If Flomo changed its schema, patch the parsing code so `body.data` matches the new envelope
Example fix
// before
if (!Array.isArray(body.data)) {
throw new CommandExecutionError('Flomo API returned malformed memo data');
}
// after
const data = Array.isArray(body?.data) ? body.data : Array.isArray(body) ? body : null;
if (!data) {
throw new CommandExecutionError(`Flomo API returned malformed memo data: ${JSON.stringify(body).slice(0, 200)}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!apiResponse || !Array.isArray(apiResponse.data)) {
throw new Error('Flomo response missing data array; aborting before map()');
} Type guard
function hasMemoData(body) {
return typeof body === 'object' && body !== null && Array.isArray(body.data);
} Try / catch
try {
const memos = await flomoMemos(filters);
} catch (err) {
if (err.message.includes('malformed memo data')) {
logRawResponseForDebugging(); // inspect actual body shape / re-auth
} else {
throw err;
}
} Prevention
- Keep the CLI updated against Flomo API changes
- Log the raw response body on parse failures for diagnosis
- Check for login-redirect HTML before JSON parsing
- Verify session validity before calling the memos endpoint
When it happens
Trigger: The Flomo API returns 200 with a body where `data` is missing, an object, a string, or null — e.g. a changed response schema, an HTML/JSON error page parsed into `{}`, or an unexpected payload from the memos endpoint.
Common situations: Flomo changes its private/API response shape; a proxy or captive portal returns HTML; the request hits a login page instead of memo JSON; stale session produces an empty object body that passes auth checks.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Malformed response from Douyin API (${method} ${url})
- API_ERROR
- API_ERROR
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
- No user message found in request
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1ad7745a435772d6.
Report an issue: GitHub.