mastra-ai/mastra · error · HTTPException
Skills API error: ${response.status} ${response.statusText}
Error message
Skills API error: ${response.status} ${response.statusText} What it means
A 502 Bad Gateway raised by `searchSkillsSh` when the skills.sh registry API responds with a non-OK HTTP status. The server proxies search requests to SKILLS_SH_API_URL and surfaces upstream failures as 502 so clients know the problem is with the upstream registry, not their query.
Source
Thrown at packages/server/src/server/handlers/skills-sh-shared.ts:153
displayName: string;
}>;
total: number;
page?: number;
pageSize?: number;
totalPages?: number;
}
/** Search skills.sh by query string. Throws HTTPException on upstream failure. */
export async function searchSkillsSh({ q, limit }: { q: string; limit: number }): Promise<SkillsShSearchResult> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), SEARCH_TIMEOUT_MS);
try {
const url = `${SKILLS_SH_API_URL}/api/skills?query=${encodeURIComponent(q)}&pageSize=${limit}`;
const response = await fetch(url, { signal: controller.signal });
if (!response.ok) {
throw new HTTPException(502, {
message: `Skills API error: ${response.status} ${response.statusText}`,
});
}
const data = (await response.json()) as UpstreamSkillsList;
return {
query: q,
searchType: 'query',
skills: data.skills.map(s => ({ id: s.skillId, name: s.name, installs: s.installs, topSource: s.source })),
count: data.total,
};
} finally {
clearTimeout(timeoutId);
}
}
/** Fetch the popular skills list from skills.sh. */
export async function getPopularSkillsSh({View on GitHub (pinned to 75dd419e61)
Solutions
- Retry the search after a short delay; upstream hiccups are often transient.
- Check skills.sh status directly (curl the API URL) to confirm an outage.
- Verify outbound network/egress from the Mastra server host (proxy, firewall, DNS).
- Inspect the status/statusText in the message (429 vs 500) to decide between backoff and outage handling.
Example fix
// before
const results = await searchSkills('react'); // throws 502 on upstream failure
// after
async function searchSkillsSafe(q) {
try { return await searchSkills(q); }
catch (e) {
if (e?.status === 502) { await new Promise(r => setTimeout(r, 1000)); return searchSkills(q); }
throw e;
}
} Defensive patterns
Strategy: retry
Try / catch
try {
const results = await searchSkills(q);
return results;
} catch (e) {
if (e instanceof MastraClientError && e.status === 502) {
// upstream skills.sh failure — retry with backoff or serve cached results
await new Promise(r => setTimeout(r, 1000));
return searchSkills(q);
}
throw e;
} Prevention
- Cache search results to tolerate transient registry outages.
- Monitor skills.sh availability from your server host.
- Confirm firewall/proxy rules allow outbound HTTPS to skills.sh.
When it happens
Trigger: Calling the builder registry search route while skills.sh is down, rate-limiting (429), returning 5xx, or an intermittent proxy/firewall altering the response.
Common situations: skills.sh outage or maintenance; network egress blocked from a self-hosted server; upstream rate limits under heavy search traffic; DNS/CDN errors producing non-OK statuses.
Related errors
- Skills API error: ${response.status} ${response.statusText}
- Token exchange failed: ${error}
- Failed to fetch user info from Auth0
- Token exchange failed: ${error}
- Failed to fetch user info from Clerk
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b3b8e5de290c64de.
Report an issue: GitHub.