jackwener/OpenCLI · error · CommandExecutionError
Manus skills returned a malformed API payload
Error message
Manus skills returned a malformed API payload
What it means
The `manus skills` command calls `skill.v1.SkillService/ListSkills` and expects the response object to contain at least one of the known skill-list keys: `userAddedSkills`, `systemSkills`, or `skills`. If the payload has none of these keys, the code concludes the API contract changed or the response is not a real skills payload and throws this CommandExecutionError. It is a defensive schema check against Manus API shape drift.
Source
Thrown at clis/manus/skills.js:30
browser: true,
siteSession: 'persistent',
navigateBefore: true,
args: [],
columns: ['ID', 'Name', 'Description', 'Source'],
func: async (page) => {
await ensureOnManus(page);
const data = requireObject(await page.evaluate(`(async () => {
${MANUS_API_CALL_JS}
return callManusAPI('skill.v1.SkillService/ListSkills', {});
})()`), 'skills');
const rows = [];
const hasUserSkills = Object.prototype.hasOwnProperty.call(data, 'userAddedSkills');
const hasSystemSkills = Object.prototype.hasOwnProperty.call(data, 'systemSkills') || Object.prototype.hasOwnProperty.call(data, 'skills');
if (!hasUserSkills && !hasSystemSkills) {
throw new CommandExecutionError('Manus skills returned a malformed API payload');
}
const userSkills = hasUserSkills ? requireArray(data.userAddedSkills, 'user skills') : [];
for (const [index, s] of userSkills.entries()) {
rows.push({
ID: requireString(s?.id || s?.uid, `user skill ${index + 1}`),
Name: requireString(s?.name, `user skill ${index + 1}`),
Description: (s.description || '—').slice(0, 80),
Source: 'user',
});
}
const systemSkills = Object.prototype.hasOwnProperty.call(data, 'systemSkills')
? requireArray(data.systemSkills, 'system skills')
: (Object.prototype.hasOwnProperty.call(data, 'skills') ? requireArray(data.skills, 'system skills') : []);
for (const [index, s] of systemSkills.entries()) {
rows.push({
ID: requireString(s?.id || s?.uid, `system skill ${index + 1}`),View on GitHub (pinned to 49907e53dc)
Solutions
- Re-login to Manus in the browser profile and retry, to rule out an auth/error response masquerading as a payload.
- Update the CLI to the latest version so it matches the current Manus ListSkills response schema.
- Inspect the raw response (call ListSkills via devtools on manus.im while logged in) to confirm the field names; report/file an issue if the schema changed.
- Wait and retry if Manus is mid-deploy; transient API instability can yield odd payloads.
Example fix
// payload Manus actually returned after a schema change
{"items": [...]} // no userAddedSkills/systemSkills/skills -> throws
// fix: update the CLI or patch the key check
// before
if (!hasUserSkills && !hasSystemSkills) throw new CommandExecutionError('Manus skills returned a malformed API payload');
// after
const hasItems = Object.prototype.hasOwnProperty.call(data, 'items');
if (!hasUserSkills && !hasSystemSkills && !hasItems) throw new CommandExecutionError('Manus skills returned a malformed API payload'); Defensive patterns
Strategy: try-catch
Type guard
function isSkillsPayload(d) {
return !!d && typeof d === 'object' &&
['userAddedSkills', 'systemSkills', 'skills'].some(k => Object.prototype.hasOwnProperty.call(d, k));
} Try / catch
try {
const rows = await run('manus skills');
} catch (e) {
if (/malformed API payload/.test(e.message)) {
console.error('Manus API schema may have changed — update the CLI and re-login, then retry.');
} else throw e;
} Prevention
- Keep the CLI updated so its expected ListSkills schema tracks Manus changes.
- Ensure the browser profile is logged in — an auth/error JSON body can masquerade as a payload.
- Before scripting, spot-check the raw ListSkills response in devtools while logged in.
- If a schema change breaks the CLI, report it rather than silently treating it as no skills.
When it happens
Trigger: The ListSkills endpoint returns a payload with no `userAddedSkills`/`systemSkills`/`skills` key — e.g. Manus renamed or restructured the response fields, an auth/anti-bot interstitial returned HTML or a different JSON body that still parsed as an object, or the response is an empty object due to a server-side change.
Common situations: Manus shipping a frontend/API update that renames response fields; the CLI's cookie-session page.evaluate getting an unexpected logged-out or error JSON response; regional/API-version differences in the skill service.
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
- coingecko returned malformed JSON: ${error?.message || error
- DuckDuckGo suggest returned malformed JSON: ${err?.message ?
- Pixiv user novel item returned malformed ${label}
- Pixiv user novels returned mismatched novel detail payload f
- Pixiv user profile returned malformed novels payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1fbf7d54f3f14ac8.
Report an issue: GitHub.