{"record":{"id":"555880b18d7232d0","repo":"jackwener/OpenCLI","slug":"label-returned-http-resp-status-555880","errorCode":null,"errorMessage":"${label} returned HTTP ${resp.status}","messagePattern":"(.+?) returned HTTP (.+?)","errorType":"http","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/packagist/utils.js","lineNumber":76,"sourceCode":"        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that packagist.org is reachable from this network.',\n        );\n    }\n    if (resp.status === 404) {\n        throw new EmptyResultError(label, `Packagist returned 404 for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(\n            `${label} returned HTTP 429 (rate limited)`,\n            'Packagist throttles bursts; wait a few seconds and retry.',\n        );\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);\n    }\n    let body;\n    try {\n        body = await resp.json();\n    }\n    catch (err) {\n        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);\n    }\n    return body;\n}\n\n/** Trim \"2026-05-05T17:32:01+00:00\" → \"2026-05-05T17:32:01Z\" so timestamps are uniform. */\nexport function trimDate(value) {\n    const s = String(value ?? '').trim();\n    if (!s) return null;\n    const noFrac = s.replace(/\\.\\d+/, '');\n    return noFrac.replace(/(?:[+-]\\d{2}:?\\d{2}|Z)?$/, 'Z');\n}","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/packagist/utils.js#L58-L94","documentation":"packagistFetch throws this when a Packagist HTTP request completes with a non-OK status other than the specially-handled 429. It signals the remote API rejected or failed the request without parsing a body. The library surfaces the raw HTTP status so callers can diagnose server- or request-side problems.","triggerScenarios":"Calling any packagistFetch-backed command (body/lookup helpers) when Packagist returns 4xx/5xx other than 429: 404 for an unknown package, 403 for blocked requests, 5xx during Packagist outages.","commonSituations":"Typos in package vendor/name causing 404; Packagist returning 503 during maintenance; corporate proxies rejecting the request with 403; deprecated or removed packages.","solutions":["Verify the package name/vendor spelling exactly matches Packagist (case-sensitive vendor).","Check https://packagist.org in a browser or `curl -I` the API URL to confirm the status is reproducible.","Retry later if the status is 5xx (Packagist-side outage).","Check proxy/VPN/firewall settings if the status is 403."],"exampleFix":"// before\nconst data = await body('symfony/does-not-exist');\n// after\nlet data;\ntry { data = await body('symfony/console'); }\ncatch (e) { console.error(`Lookup failed: ${e.message}`); }","handlingStrategy":"try-catch","validationCode":"// Pre-check the resource exists on Packagist (optional)\nconst res = await fetch(`https://repo.packagist.org/p2/${name}.json`);\nif (!res.ok) throw new Error(`Package ${name} unreachable: HTTP ${res.status}`);","typeGuard":null,"tryCatchPattern":"try {\n  const data = await body(pkg);\n} catch (err) {\n  if (/HTTP 404/.test(err.message)) console.error(`Unknown package: ${pkg}`);\n  else if (/HTTP 5\\d\\d/.test(err.message)) retryLater();\n  else throw err;\n}","preventionTips":["Double-check package vendor/name spelling against packagist.org.","Handle 429 and 5xx with backoff before giving up.","Monitor Packagist status during CI runs."],"tags":["http","network","packagist"],"backgroundTag":"http-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}