mastra-ai/mastra · error
Pull request subscriptions returned an invalid response.
Error message
Pull request subscriptions returned an invalid response.
What it means
After a successful HTTP fetch of pull request subscriptions, the client validates the JSON body: it must be an object with a 'subscriptions' array. If not, it throws 'Pull request subscriptions returned an invalid response.' This guards against contract drift between server and client instead of crashing later on malformed rows.
Source
Thrown at mastracode/factory-ui/src/ui/domains/factory/services/githubSubscriptions.ts:51
isPullRequestStatus(value.status) &&
typeof value.url === 'string'
);
}
export async function listPullRequestSubscriptions(
baseUrl: string,
resourceId: string,
threadId: string,
projectPath?: string,
): Promise<PullRequestSubscription[]> {
const params = new URLSearchParams({ resourceId, threadId });
if (projectPath) params.set('scope', projectPath);
const response = await fetch(`${baseUrl}/web/github/subscriptions?${params}`, { credentials: 'include' });
if (!response.ok) throw new Error(`Failed to load pull request subscriptions (${response.status}).`);
const body: unknown = await response.json();
if (!isRecord(body) || !Array.isArray(body.subscriptions)) {
throw new Error('Pull request subscriptions returned an invalid response.');
}
// one bad row must not hide every other pull request; warn so a widened server enum is not silent
const subscriptions = body.subscriptions.filter(isPullRequestSubscription);
const dropped = body.subscriptions.length - subscriptions.length;
if (dropped > 0 && import.meta.env.DEV) {
console.warn(`Dropped ${dropped} pull request subscription(s) the client does not understand.`);
}
return subscriptions;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Log/inspect the actual response body to see what the server returned
- Confirm the server version matches the client's expected shape ({ subscriptions: [...] })
- Check that the request is not being answered by an HTML page (auth redirect or SPA fallback) instead of the API
- Upgrade or align the server route with the factory-ui client contract
Example fix
// before
// server: res.json({ data: subs })
// after
// server: res.json({ subscriptions: subs }) Defensive patterns
Strategy: type-guard
Validate before calling
const res = await fetch(url, { credentials: 'include' });
const text = await res.text();
if (!text.trim().startsWith('{')) throw new Error('Expected JSON but got: ' + text.slice(0, 80)); // catches HTML proxy/login fallbacks Type guard
function isSubscriptionsResponse(v: unknown): v is { subscriptions: unknown[] } {
return typeof v === 'object' && v !== null && 'subscriptions' in v && Array.isArray((v as { subscriptions: unknown }).subscriptions);
} Try / catch
try {
const subs = await listPullRequestSubscriptions(baseUrl, resourceId, threadId);
} catch (err) {
if (err instanceof Error && err.message.includes('invalid response')) {
// contract drift or HTML response: log raw payload and show empty state
console.error('Subscriptions response shape mismatch', err);
renderEmptyState();
} else throw err;
} Prevention
- Pin/align client and server response contracts; add a shared schema/type import
- Check for auth middleware that returns 200 HTML instead of redirecting
- Add an integration test asserting the endpoint's exact JSON shape
- Disable SPA/HTML fallbacks for /web/api-style routes in dev proxies
When it happens
Trigger: The endpoint returned 200 but with a body that is not a record or lacks a 'subscriptions' array: a proxy/login page returning HTML, an error JSON like {"error":"..."} with 200 status, an API version change renaming/restructuring the field, or an empty/malformed response body.
Common situations: Auth middleware intercepts and returns 200 HTML, server deployed with an older/newer response shape ({"data":{...}} instead of {"subscriptions":[...]}), or a dev proxy returning an index.html fallback for unknown routes.
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.
Related errors
- Query parameter "status" must be "draft" or "published"
- Agent ID is required
- Query parameters "versionId" and "status" are mutually exclu
- Query parameter "status" must be "draft" or "published"
- Missing required query param: ${label}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/7b30a09240250ea1.
Report an issue: GitHub.