{"record":{"id":"548fe2c90ec4b705","repo":"jackwener/OpenCLI","slug":"linux-do-request-failed-http-result-status","errorCode":null,"errorMessage":"linux.do request failed: HTTP ${result.status ?? 'unknown'}","messagePattern":"linux\\.do request failed: HTTP (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linux-do/feed.js","lineNumber":106,"sourceCode":"        status: res.status,\n        data,\n        error: data === null ? 'Response is not valid JSON' : '',\n      };\n    } catch (error) {\n      return {\n        ok: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  })()`);\n    if (!result) {\n        throw new CommandExecutionError('linux.do returned an empty browser response');\n    }\n    if (result.status === 401 || result.status === 403) {\n        throw new AuthRequiredError('linux.do', 'linux.do requires an active signed-in browser session');\n    }\n    if (!result.ok) {\n        throw new CommandExecutionError(result.error || `linux.do request failed: HTTP ${result.status ?? 'unknown'}`);\n    }\n    if (result.error) {\n        throw new CommandExecutionError(result.error, 'Please verify your linux.do session is still valid');\n    }\n    return result.data;\n}\nfunction findMatchingTag(records, value) {\n    const raw = value.trim();\n    const normalized = normalizeLookupValue(value);\n    return /^\\d+$/.test(raw)\n        ? records.find((item) => item.id === Number(raw)) ?? null\n        : records.find((item) => normalizeLookupValue(item.name) === normalized)\n            ?? records.find((item) => normalizeLookupValue(item.slug) === normalized)\n            ?? null;\n}\nfunction findMatchingCategory(records, value) {\n    const raw = value.trim();\n    const normalized = normalizeLookupValue(value);","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linux-do/feed.js#L88-L124","documentation":"When the browser-mediated request to linux.do completes but result.ok is false (any status other than 401/403), fetchLinuxDoJson throws CommandExecutionError carrying result.error or a synthesized 'linux.do request failed: HTTP <status>' message. The status may be 'unknown' when the browser wrapper could not determine one. This is the library's generic non-2xx HTTP failure path for the Discourse API.","triggerScenarios":"Any fetchLinuxDoJson call (data, subData) where the site returns a non-ok, non-401/403 response: HTTP 404 for a mistyped/removed tag or category id, 429 rate limiting, 5xx server errors, network interception producing no status, or DNS/proxy failures surfaced through the browser.","commonSituations":"Passing a stale or invalid tag/category id from an old cache; hitting linux.do too frequently and getting rate-limited; transient linux.do or Cloudflare outages; corporate proxy interfering with the automated browser.","solutions":["Read the HTTP status in the message: 404 means the tag/category doesn't exist — run `opencli linux-do tags` / `categories` to list valid ones","For 429, wait and back off before retrying; reduce polling frequency","For 5xx or unknown status, retry after a delay; check https://linux.do availability in a normal browser","Clear stale metadata cache in ~/.opencli/cache/linux-do if ids no longer resolve"],"exampleFix":"// before (shell)\nopencli linux-do feed --tag 99999   // linux.do request failed: HTTP 404\n// after (shell)\nopencli linux-do tags                 # confirm the tag id exists\nopencli linux-do feed --tag 4","handlingStrategy":"retry","validationCode":"function isTransientStatus(status) {\n    return status == null || status === 429 || (status >= 500 && status <= 599);\n}\n// Only auto-retry transient statuses; surface 404 etc. immediately","typeGuard":"function isOkResult(result) {\n    return Boolean(result) && typeof result === 'object' &&\n        result.ok === true && !('error' in result && result.error);\n}","tryCatchPattern":"import { CommandExecutionError } from '@jackwener/opencli/errors';\ntry {\n    const topics = await data();\n} catch (err) {\n    if (err instanceof CommandExecutionError && /HTTP (429|5\\d\\d|unknown)/.test(err.message)) {\n        await new Promise(r => setTimeout(r, 5000));\n        // retry once, then surface\n    } else {\n        throw err;\n    }\n}","preventionTips":["Match tag/category values against `linux-do tags` / `categories` output before fetching feeds","Back off on 429 instead of hammering the endpoint","Refresh the metadata cache (TTL 24h in ~/.opencli/cache/linux-do) after forum changes","Check linux.do availability in a normal browser before debugging the CLI"],"tags":["http","network","cli","rate-limit"],"backgroundTag":"http-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}