justjavac/wechat-miniapp-radar · warning · Error
HTTP ${response.status}
Error message
HTTP ${response.status} What it means
Thrown by fetchJson() in lib/enrichment.ts when an HTTP response is non-OK; it raises a bare `HTTP <status>` carrying only the status code. fetchJson() is the internal helper used to pull GitHub repo metadata and npm registry data during signal collection, with a 10s AbortController timeout (an abort surfaces as a different AbortError, not this message). The public collector collectResourceSignal() wraps every fetchJson() call in try/catch and converts the thrown error into a CollectedSignal with ok:false and the message in .error, so it never escapes to top-level code.
Source
Thrown at lib/enrichment.ts:94
return parts[1] ?? null;
} catch {
return null;
}
}
async function fetchJson<T>(url: string, headers: HeadersInit = {}) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000);
try {
const response = await fetch(url, {
headers: {
"user-agent": "miniprogram-radar",
...headers
},
signal: controller.signal
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return (await response.json()) as T;
} finally {
clearTimeout(timeout);
}
}
async function fetchHead(url: string) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 8000);
try {
const response = await fetch(url, {
method: "HEAD",
headers: {
"user-agent": "miniprogram-radar"
},
redirect: "follow",
signal: controller.signalView on GitHub (pinned to 02a010ecea)
Solutions
- Set GITHUB_TOKEN to raise GitHub limits from 60 to about 5000 req/hour (collectResourceSignal already attaches it as Bearer when present).
- For 404s, correct or remove the resource URL in data/resources.yaml then run npm run generate.
- For transient 403-rate-limit or 5xx, retry with backoff or reduce runEnrichment({ limit }).
- Always read the returned CollectedSignal.ok/.error rather than letting fetchJson propagate.
Example fix
// before
const repo = await fetchJson<GitHubRepo>(url); // throws 'HTTP 403'
// after (the pattern collectResourceSignal already uses)
try {
const repo = await fetchJson<GitHubRepo>(url, headers);
} catch (error) {
return { ok: false, error: error instanceof Error ? error.message : String(error) };
} Defensive patterns
Strategy: try-catch
Validate before calling
const needsGithubToken = resources.some(r => r.url.startsWith('https://github.com/'));
if (needsGithubToken && !process.env.GITHUB_TOKEN) {
console.warn('GITHUB_TOKEN unset; GitHub fetches may 403 after 60 req/hour');
} Try / catch
try {
const data = await fetchJson<T>(url, headers);
} catch (error) {
const message = error instanceof Error ? error.message : String(error); // e.g. 'HTTP 403'
return { ok: false, payload: {}, error: message } satisfies CollectedSignal;
} Prevention
- Always set GITHUB_TOKEN for enrichment jobs.
- Wrap every fetchJson call like collectResourceSignal does; never let it propagate.
- Cap concurrency with runEnrichment({ limit }) to stay under rate ceilings.
When it happens
Trigger: GitHub repos API returns 403 (unauthenticated rate limit of 60 req/hour, or an expired GITHUB_TOKEN); 404 for a renamed or deleted repo or npm package; 401 for a bad token; 5xx from the registry; a registry/site returning a non-2xx status for an otherwise valid URL.
Common situations: Running enrichment locally without GITHUB_TOKEN and hitting the 60/hr limit; a tracked repo renamed or moved; npm package unpublished; flaky 5xx during a bulk run; GITHUB_TOKEN expired but still set in env.
Related errors
AI-assisted analysis of justjavac/wechat-miniapp-radar@02a010ecea (2026-08-12).
Data as JSON: /api/errors/522eea4a7a002342.
Report an issue: GitHub.