mastra-ai/mastra · error · WorkspaceSkillInvocationError
invalid_response
invalid_response
Error message
Skill invocation returned an invalid response.
What it means
Thrown by requestWorkspaceSkill when the skill-invocation endpoint returns HTTP 200 but the body is not parseable JSON. The client expects a JSON envelope with skill and message fields; non-JSON output (e.g. an HTML error page from a proxy) fails parsing and produces this 502-coded WorkspaceSkillInvocationError.
Source
Thrown at mastracode/factory-ui/src/ui/domains/chat/services/agentControllerClient.ts:107
async function requestWorkspaceSkill(
action: 'prepare' | 'invoke',
{ agentControllerId, resourceId, scope, name, arguments: skillArguments, baseUrl = '' }: InvokeWorkspaceSkillArgs,
): Promise<{ skill: string; message: string }> {
const response = await fetch(
`${baseUrl}/web/agent-controller/${encodeURIComponent(agentControllerId)}/skills/${action}`,
{
method: 'POST',
credentials: 'include',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ resourceId, scope, name, arguments: skillArguments }),
},
);
if (response.ok) {
let result: { skill?: unknown; message?: unknown };
try {
result = (await response.json()) as typeof result;
} catch {
throw new WorkspaceSkillInvocationError(
'Skill invocation returned an invalid response.',
502,
'invalid_response',
);
}
if (typeof result.skill === 'string' && typeof result.message === 'string') {
return { skill: result.skill, message: result.message };
}
throw new WorkspaceSkillInvocationError('Skill invocation returned an invalid response.', 502, 'invalid_response');
}
let error: { error?: unknown; message?: unknown } = {};
try {
error = (await response.json()) as typeof error;
} catch {
// Preserve a useful status-based fallback when an intermediary returns HTML.
}
const code = typeof error.error === 'string' ? error.error : 'skill_invocation_failed';View on GitHub (pinned to 75dd419e61)
Solutions
- Check the network tab: inspect the 200 response body of the skill request to see what was actually returned.
- Fix the proxy/intermediary returning non-JSON (or point the client at the correct API base URL).
- Ensure the skill API route always responds with Content-Type: application/json, including error paths.
Example fix
// before (server)
return new Response('done');
// after (server)
return Response.json({ skill: skillName, message: 'done' }); Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(url, { method: 'POST', body });
const ct = res.headers.get('content-type') ?? '';
if (!ct.includes('application/json')) throw new Error('Skill endpoint returned non-JSON'); Type guard
function isSkillResult(v: unknown): v is { skill: string; message: string } {
return typeof v === 'object' && v !== null && typeof (v as any).skill === 'string' && typeof (v as any).message === 'string';
} Try / catch
try {
const { skill, message } = await prepareWorkspaceSkill(args);
} catch (e) {
if (e instanceof WorkspaceSkillInvocationError && e.code === 'invalid_response') {
console.error('Skill endpoint returned a non-JSON 200 body — check proxy/route', e.status);
}
} Prevention
- Assert Content-Type: application/json on all skill routes, including error paths.
- Keep dev-server proxies pointed at the correct API port.
- Add an integration test asserting the skill route's response shape.
When it happens
Trigger: POST to the skill endpoint returns ok=true with a non-JSON body — e.g. an intermediary (nginx/CDN) intercepting, a dev-server proxy misroute returning HTML, or the route streaming text instead of JSON.
Common situations: Reverse proxy returning a cached HTML page with status 200; API route changed and now returns plain text; dev server proxy pointing at the wrong port.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- skill_invocation_failed
- Invalid state token payload
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
- Query parameter "status" must be "draft" or "published"
- Agent ${agentId} not found
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b45a7ab4cc1ac940.
Report an issue: GitHub.