Crosstalk-Solutions/project-nomad · error · Error
HTTP from
Error message
HTTP ${resp.status} from ${MANIFEST_URL} What it means
Thrown by DrugLabelManifestFetcher-like fetchManifest() when fetching MANIFEST_URL returns a non-2xx HTTP status. The fetch itself succeeded at the transport level, but the FDA endpoint responded with an error status, so the manifest JSON is never parsed.
Solutions
- Retry after a short wait — transient 5xx/429 from the FDA API usually clears.
- Check the URL in a browser/curl: curl -i $MANIFEST_URL to see the actual status body.
- If 404/410, verify the manifest endpoint hasn't changed in the FDA openfda/drug-labels API docs.
- If 429, add backoff between job runs or reduce download frequency.
Example fix
// before
const resp = await fetch(MANIFEST_URL)
if (!resp.ok) throw new Error(`HTTP ${resp.status} from ${MANIFEST_URL}`)
// after — retry with backoff on transient statuses
async function fetchManifestRetry(retries = 3) {
for (let i = 0; i <= retries; i++) {
const resp = await fetch(MANIFEST_URL)
if (resp.ok) return parseDrugLabelManifest(await resp.json())
if (resp.status >= 500 || resp.status === 429) {
await new Promise(r => setTimeout(r, 2 ** i * 1000))
continue
}
throw new Error(`HTTP ${resp.status} from ${MANIFEST_URL}`)
}
throw new Error(`HTTP retries exhausted for ${MANIFEST_URL}`)
} Defensive patterns
Strategy: retry
Validate before calling
// preflight reachability (optional, cheap)
const resp = await fetch(MANIFEST_URL, { method: 'HEAD' }).catch(() => null)
if (!resp?.ok) { /* defer the job instead of failing */ } Try / catch
catch (err) {
if (err instanceof Error && /^HTTP \d+ from /.test(err.message)) {
const status = Number(err.message.match(/^HTTP (\d+)/)?.[1])
if (status >= 500 || status === 429) return retryWithBackoff()
}
throw err
} Prevention
- Wrap manifest fetches in retry-with-backoff for 5xx/429.
- Cache the last good manifest to ride out short outages.
- Alert on repeated non-2xx so endpoint drift is caught early.
When it happens
Trigger: fetch(MANIFEST_URL) resolves with resp.ok false: FDA API is down or returning 5xx, rate limiting (429), moved endpoint (404/301), proxy or captive portal returning 4xx.
Common situations: Temporary FDA service outage, rate limit hit during repeated testing, changed/retired endpoint path, corporate proxy intercepting the request, DNS hijack returning an error page.
Related errors
- Base map assets are missing and could not be downloaded…
- Could not fetch directory listing from the provided URL
- ${error.message}
- Failed to download tar file
- Failed to fetch available versions for this service.
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/02fd54d9b15e0d76.
Report an issue: GitHub.
Appendix: source
Thrown at admin/app/jobs/download_drug_data_job.ts:312
}
private async fetchManifest(): Promise<DrugLabelManifest> {
return DownloadDrugDataJob.fetchManifest()
}
/**
* Fetch + parse the openFDA download manifest. The SINGLE source of truth for
* the openFDA manifest call (Maxim 4): the download job uses it on pass 0, and
* the freshness check (DrugReferenceService.checkForUpdate, driven by
* attemptAutoUpdate) reuses it so there is exactly one place that knows the URL and the
* offline-error translation.
*/
static async fetchManifest(): Promise<DrugLabelManifest> {
let json: unknown
try {
const resp = await fetch(MANIFEST_URL)
if (!resp.ok) {
throw new Error(`HTTP ${resp.status} from ${MANIFEST_URL}`)
}
json = await resp.json()
} catch (err) {
const msg = err instanceof Error ? err.message : String(err)
if (
msg.includes('ENOTFOUND') ||
msg.includes('ECONNREFUSED') ||
msg.includes('ECONNRESET') ||
msg.includes('fetch failed')
) {
throw new Error(`No internet — connect to download FDA drug data. (${msg})`)
}
throw err
}
return parseDrugLabelManifest(json)
}
private async writeDownloadState(View on GitHub (pinned to 0bd1c6f4f9)