mastra-ai/mastra · error
Request failed (${response.status}) / server-provided messag
Error message
Request failed (${response.status}) / server-provided message What it means
fetchFactoryDecisions/actOnFactoryDecision hit the factory decisions API and throwRequestError converts any non-OK HTTP response into a thrown Error. The message prefers the server-provided body message/error field and falls back to a generic 'Request failed (<status>)'. This surfaces backend rejection (auth, bad params, server error) to the UI layer.
Source
Thrown at mastracode/factory-ui/src/ui/domains/factory/services/decisions.ts:48
createdAt: string;
updatedAt: string;
completedAt: string | null;
}
export interface FactoryDecisionPage {
decisions: FactoryDecisionSummary[];
nextCursor?: string;
}
async function throwRequestError(response: Response): Promise<never> {
let message = `Request failed (${response.status})`;
try {
const body = (await response.json()) as { error?: string; message?: string };
message = body.message ?? body.error ?? message;
} catch {
// Keep the status-based fallback for non-JSON responses.
}
throw new Error(message);
}
export async function fetchFactoryDecisions(
baseUrl: string,
githubProjectId: string,
options: { statuses?: FactoryDecisionStatus[]; before?: string; limit?: number } = {},
): Promise<FactoryDecisionPage> {
const query = new URLSearchParams();
if (options.statuses?.length) query.set('statuses', options.statuses.join(','));
if (options.before) query.set('before', options.before);
if (options.limit) query.set('limit', String(options.limit));
const suffix = query.size > 0 ? `?${query}` : '';
const response = await fetch(
`${baseUrl}/web/factory/projects/${encodeURIComponent(githubProjectId)}/decisions${suffix}`,
{ headers: { Accept: 'application/json' }, credentials: 'include' },
);
if (!response.ok) return throwRequestError(response);
return (await response.json()) as FactoryDecisionPage;View on GitHub (pinned to 75dd419e61)
Solutions
- Inspect error.message: if it contains the server message, fix the request it describes; otherwise check response status via a network tab
- Verify the user session/auth cookie is valid for the factory baseUrl
- Validate statuses/before/limit values against the current FactoryDecisionStatus enum and API limits
- Retry after confirming the factory backend is healthy if status is 5xx
Example fix
// before
const decisions = await fetchFactoryDecisions(baseUrl, projectId, { statuses: ['unknown-status'] });
// after
const decisions = await fetchFactoryDecisions(baseUrl, projectId, { statuses: ['pending'] satisfies FactoryDecisionStatus[] }); Defensive patterns
Strategy: try-catch
Validate before calling
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
if (!isNonEmptyString(baseUrl) || !isNonEmptyString(githubProjectId)) throw new Error('baseUrl and githubProjectId are required');
const validStatuses = new Set<string>(['pending', 'approved', 'rejected']); // keep in sync with FactoryDecisionStatus
if (options.statuses && !options.statuses.every(s => validStatuses.has(s))) throw new Error('Invalid status filter'); Type guard
function isFactoryDecisionStatus(v: unknown): v is FactoryDecisionStatus {
return typeof v === 'string' && ['pending', 'approved', 'rejected'].includes(v);
} Try / catch
try {
const decisions = await fetchFactoryDecisions(baseUrl, githubProjectId, { statuses });
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (/401|403/.test(msg)) showLoginPrompt();
else if (/5\d\d/.test(msg)) retryLater();
else showError(msg);
} Prevention
- Keep the client FactoryDecisionStatus enum in sync with the server enum
- Always send credentials: 'include' and handle 401 by redirecting to login
- Validate limit/before pagination parameters before calling
- Wrap all factory service calls in a shared error boundary that parses the status from the message
When it happens
Trigger: Any response with response.ok === false from GET factory decisions (with statuses/before/limit query params) or POST/PATCH actOnFactoryDecision, including 401/403 auth failures, invalid githubProjectId, bad query params (limit out of range, malformed before cursor), or 5xx server errors.
Common situations: Expired or missing session cookie (credentials), requesting decisions with a status enum value the server no longer accepts after a version change, paginating past the last page with an invalid 'before' cursor, or the factory server being down (502/503).
Related errors
- Perplexity Search request failed with status ${response.stat
- Request failed (${res.status}) / server-provided message
- Failed to load pull request subscriptions (${response.status
- Request failed (${res.status}) / server-provided message
- Failed to fetch Copilot models: ${response.status} ${respons
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d57c84d0a447b293.
Report an issue: GitHub.