jackwener/OpenCLI · error · CommandExecutionError
Manus credits returned a malformed API payload
Error message
Manus credits returned a malformed API payload
What it means
The manus credits command calls user.v1.UserService/GetAvailableCredits and throws this CommandExecutionError when the response object contains none of the expected credit fields (totalCredits, freeCredits, periodicCredits, refreshCredits). It means the API responded but with a payload the command cannot interpret as credits data.
Source
Thrown at clis/manus/credits.js:26
access: 'read',
description: 'Show Manus credit balance and refresh details.',
domain: MANUS_DOMAIN,
strategy: Strategy.COOKIE,
browser: true,
siteSession: 'persistent',
navigateBefore: true,
args: [],
columns: ['Field', 'Value'],
func: async (page) => {
await ensureOnManus(page);
const c = requireObject(await page.evaluate(`(async () => {
${MANUS_API_CALL_JS}
return callManusAPI('user.v1.UserService/GetAvailableCredits', {});
})()`), 'credits');
if (!['totalCredits', 'freeCredits', 'periodicCredits', 'refreshCredits'].some((key) => c[key] != null)) {
throw new CommandExecutionError('Manus credits returned a malformed API payload');
}
return [
{ Field: 'Total Credits', Value: c.totalCredits ?? '—' },
{ Field: 'Free Credits', Value: c.freeCredits ?? '—' },
{ Field: 'Periodic Credits', Value: c.periodicCredits ?? '—' },
{ Field: 'Pro Monthly Credits', Value: c.proMonthlyCredits ?? '—' },
{ Field: 'Refresh Credits', Value: c.refreshCredits ?? '—' },
{ Field: 'Max Refresh Credits', Value: c.maxRefreshCredits ?? '—' },
{ Field: 'Next Refresh', Value: c.nextRefreshTime || '—' },
{ Field: 'Refresh Interval', Value: c.refreshInterval || '—' },
];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Refresh the session by re-running the manus auth/login flow, then retry the credits command
- Log the raw `c` object from the evaluate result to see what GetAvailableCredits actually returned
- Check whether Manus changed the GetAvailableCredits response schema and update the expected keys in clis/manus/credits.js
- Retry later — transient gateway/bot-challenge responses can masquerade as malformed payloads
Example fix
// before
if (!['totalCredits', 'freeCredits', 'periodicCredits', 'refreshCredits'].some((key) => c[key] != null)) {
throw new CommandExecutionError('Manus credits returned a malformed API payload');
}
// after (include raw payload for diagnosability)
if (!['totalCredits', 'freeCredits', 'periodicCredits', 'refreshCredits'].some((key) => c[key] != null)) {
throw new CommandExecutionError(`Manus credits returned a malformed API payload: ${JSON.stringify(c).slice(0, 500)}`);
} Defensive patterns
Strategy: validation
Validate before calling
const credits = await page.evaluate(`(async () => {
${MANUS_API_CALL_JS}
return callManusAPI('user.v1.UserService/GetAvailableCredits', {});
})()`);
const keys = ['totalCredits','freeCredits','periodicCredits','refreshCredits'];
if (!credits || !keys.some(k => credits[k] != null)) {
throw new Error('GetAvailableCredits payload lacks credit fields: ' + JSON.stringify(credits));
} Type guard
function hasCreditFields(c) {
return c != null && typeof c === 'object' &&
['totalCredits','freeCredits','periodicCredits','refreshCredits'].some(k => c[k] != null);
} Try / catch
try {
const rows = await manusCredits();
} catch (e) {
if (e instanceof CommandExecutionError && /malformed API payload/.test(e.message)) {
await refreshManusSession();
return manusCredits(); // one retry after re-auth
}
throw e;
} Prevention
- Keep a current session — a stale session can yield error envelopes instead of credit data
- When Manus ships API updates, diff the GetAvailableCredits response against expected keys
- Validate the payload shape before formatting output rows
- Capture the raw payload in logs to distinguish schema drift from bot-challenge responses
When it happens
Trigger: GetAvailableCredits returns 200/OK with a body lacking all four credit keys — e.g. an empty object, an error envelope, or a response whose field names changed after a Manus API update.
Common situations: Manus renamed or restructured credit fields in a newer API version; the session is valid but the account tier doesn't expose credit fields; a gateway/anti-bot layer returned a 200 HTML or challenge payload instead of the RPC result; RPC responded with an error status the wrapper still surfaced as an object.
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
- Codex extract-diff returned an invalid payload.
- LinkedIn sent invitations returned a malformed extraction pa
- LinkedIn messengerMessages API returned an unexpected respon
- Unexpected Manus probe: ${JSON.stringify(probe)}
- Pixiv bookmarks returned malformed payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3541989a07e77499.
Report an issue: GitHub.