{"record":{"id":"57bbbc93db90b9e9","repo":"jackwener/OpenCLI","slug":"label-request-failed-err-message-err-c","errorCode":null,"errorMessage":"${label} request failed: ${err?.message ?? err}. Check that hub.docker.com is reachable from this network.","messagePattern":"(.+?) request failed: (.+?)\\. Check that hub\\.docker\\.com is reachable from this network\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"critical","filePath":"clis/dockerhub/utils.js","lineNumber":75,"sourceCode":"            `dockerhub image \"${input}\" is not a valid repository slug`,\n            'Use lowercase letters / digits / \"._-\", optionally prefixed with \"<owner>/\".',\n        );\n    }\n    if (name.length < 2 || name.length > 255) {\n        throw new ArgumentError(\n            `dockerhub image \"${input}\" name must be 2-255 chars`,\n        );\n    }\n    return { owner, name };\n}\n\nexport async function hubFetch(url, label) {\n    let resp;\n    try {\n        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 hub.docker.com is reachable from this network.',\n        );\n    }\n    if (resp.status === 404) {\n        throw new EmptyResultError(label, `Docker Hub returned 404 for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(\n            `${label} returned HTTP 429 (rate limited)`,\n            'Docker Hub throttles anonymous traffic; 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 {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dockerhub/utils.js#L57-L93","documentation":"hubFetch wraps fetch calls to hub.docker.com and converts network-level failures into CommandExecutionError with the label prefix. Thrown when the HTTP request itself fails (DNS failure, connection refused, timeout, TLS error) before a response is received.","triggerScenarios":"Calling any dockerhub command (search, tags, info) while offline or behind a blocking firewall/proxy; hub.docker.com DNS not resolving; corporate proxy rejecting HTTPS; fetch aborting on timeout.","commonSituations":"CI runners without internet egress; Docker Hub rate-limit/block via network appliance; VPN changes breaking DNS; misconfigured HTTP(S)_PROXY environment variables.","solutions":["Verify network connectivity: curl -I https://hub.docker.com","Check/fix HTTP(S)_PROXY / NO_PROXY env vars for the environment","Retry after transient network issues or add backoff/retry around the command","Check firewall/DNS rules allowing egress to hub.docker.com"],"exampleFix":"// before\nawait hubFetch(url, 'dockerhub search'); // no retry\n// after\nfor (let i = 0; i < 3; i++) {\n  try { return await hubFetch(url, 'dockerhub search'); }\n  catch (e) { if (i === 2) throw e; await new Promise(r => setTimeout(r, 2 ** i * 500)); }\n}","handlingStrategy":"retry","validationCode":"// preflight\nconst ok = await fetch('https://hub.docker.com/v2/', { method: 'HEAD' }).then(r => r.ok).catch(() => false); if (!ok) throw new Error('hub.docker.com unreachable from this network');","typeGuard":null,"tryCatchPattern":"try { body = await hubFetch(url, 'dockerhub search'); } catch (e) { if (e instanceof CommandExecutionError && e.message.includes('request failed')) { await backoff(3); body = await hubFetch(url, 'dockerhub search'); } else throw e; }","preventionTips":["Check egress/proxy settings in CI and containers","Set HTTP(S)_PROXY correctly for restricted networks","Implement exponential-backoff retries for transient failures","Monitor Docker Hub reachability before batch jobs"],"tags":["network","http","fetch","dockerhub"],"backgroundTag":"connection-refused","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}