jackwener/OpenCLI · error · CommandExecutionError
Lobsters API HTTP ${res.status} for story ${shortId}
Error message
Lobsters API HTTP ${res.status} for story ${shortId} What it means
Thrown by fetchStory in clis/lobsters/read.js:26 when the lobste.rs JSON endpoint returns a non-OK status other than 404. 404 is converted to EmptyResultError; anything else (5xx, 403 rate-limited, network-edge errors surfaced as status) becomes this generic CommandExecutionError wrapping the HTTP status and the story short id. It signals the request reached the Lobsters API but the API rejected or failed to serve it.
Source
Thrown at clis/lobsters/read.js:26
* just need one HTTP call, then build a children map and DFS.
*
* Output rows:
* - first row is the story itself (`type=POST`)
* - each subsequent row is a comment, indented by depth (`L0`, `L1`, …)
* - `[+N more replies]` summary rows whenever depth/limit cuts in
*/
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
const LOBSTERS_STORY_BASE = 'https://lobste.rs/s';
async function fetchStory(shortId) {
const res = await fetch(`${LOBSTERS_STORY_BASE}/${shortId}.json`);
if (res.status === 404) {
throw new EmptyResultError(`lobsters/${shortId}`, 'Story not found');
}
if (!res.ok) {
throw new CommandExecutionError(`Lobsters API HTTP ${res.status} for story ${shortId}`, 'Check the short id');
}
return res.json();
}
function requirePositiveInt(value, label) {
if (!Number.isInteger(value) || value <= 0) {
throw new ArgumentError(`${label} must be a positive integer`);
}
return value;
}
function requireMinInt(value, min, label) {
if (!Number.isInteger(value) || value < min) {
throw new ArgumentError(`${label} must be an integer >= ${min}`);
}
return value;
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Check https://lobste.rs is reachable in a browser and inspect the actual HTTP status from the message
- Retry after a delay if the status is 429/5xx — Lobsters rate-limits and has outages
- Verify the short id is a valid lowercase-alphanumeric id (regex ^[a-z0-9]+$ passes before fetch)
- Check for proxy/VPN/firewall interference with lobste.rs requests
- If persistent, capture res body/status and report to Lobsters or the CLI maintainers
Example fix
// before
const story = await fetchStory(shortId);
// after
try {
const story = await fetchStory(shortId);
} catch (e) {
if (/HTTP 429|HTTP 5\d\d/.test(e.message)) {
await new Promise(r => setTimeout(r, 5000));
return fetchStoryWithRetry(shortId);
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
const shortId = String(id || '').trim();
if (!/^[a-z0-9]+$/.test(shortId)) throw new Error(`Invalid short id: ${id}`); Type guard
function isValidShortId(id) {
return typeof id === 'string' && /^[a-z0-9]+$/.test(id.trim());
} Try / catch
try {
const story = await fetchStory(id);
} catch (e) {
if (/HTTP (429|5\d\d)/.test(e.message)) {
await sleep(5000);
return fetchStory(id); // bounded retries
}
throw e;
} Prevention
- Validate the short id format before calling
- Back off and retry on 429/5xx only
- Poll Lobsters status before bulk runs
- Avoid high-frequency scripted reads that trip rate limits
When it happens
Trigger: Calling `lobsters read <short_id>` where the GET https://lobste.rs/s/<short_id>.json returns e.g. 500/502/503 (Lobsters outage or Cloudflare issue) or 403/429 (rate limiting, blocked IP). Only statuses other than 404 produce this.
Common situations: Lobsters is down or under maintenance; a corporate proxy/CDN blocks lobste.rs; short-id typos that accidentally hit an edge route returning 403/410 instead of 404; aggressive scripted polling triggering 429 rate limits.
Related errors
- HTTP_ERROR
- Xiaoyuzhou API request failed with HTTP ${response.status}${
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
- autohome ${contextHint} HTTP ${resp.status}
- HTTP ${result.httpStatus} from /api/organizations
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4e62188f9d832aa2.
Report an issue: GitHub.