jackwener/OpenCLI · error · CommandExecutionError
stack exchange API error: ${data.error_message || data.error
Error message
stack exchange API error: ${data.error_message || data.error_name} What it means
The Stack Exchange API responded with valid JSON that carries an error_id, meaning the API itself rejected the request (e.g. no site matched, invalid parameter, throttled). seFetch surfaces error_message/error_name verbatim. The second argument hints that opening the URL in a browser shows the canonical error context.
Source
Thrown at clis/stackoverflow/utils.js:77
} catch (error) {
throw new CommandExecutionError(`stack exchange request failed: ${error?.message || error}`);
}
if (resp.status === 429) {
throw new CommandExecutionError('stack exchange returned HTTP 429 (rate limited)', 'Wait a few seconds and retry, or lower --limit.');
}
if (!resp.ok) {
let body = '';
try { body = (await resp.json())?.error_message || ''; } catch { /* ignore */ }
throw new CommandExecutionError(`stack exchange HTTP ${resp.status}: ${body || resp.statusText}`);
}
let data;
try {
data = await resp.json();
} catch (error) {
throw new CommandExecutionError(`stack exchange returned malformed JSON: ${error?.message || error}`);
}
if (data?.error_id) {
throw new CommandExecutionError(
`stack exchange API error: ${data.error_message || data.error_name}`,
'Inspect the URL in a browser for the canonical error context.',
);
}
return data;
}
/** Convert SE epoch seconds to YYYY-MM-DD. */
export function epochToDate(value) {
if (value == null || value === '') return '';
const n = Number(value);
if (!Number.isFinite(n) || n <= 0) return '';
return new Date(n * 1000).toISOString().slice(0, 10);
}
/** Throw EmptyResultError when an /items array is empty. */
export function ensureItems(data, label) {
const items = Array.isArray(data?.items) ? data.items : [];View on GitHub (pinned to 49907e53dc)
Solutions
- Read error_message in the thrown message and fix the offending parameter (usually `site`)
- Check daily quota: anonymous requests are limited to 300/day per IP; register an app key to raise it to 10,000
- Open the failing request URL in a browser to see the full API error payload
- Verify the site parameter against https://api.stackexchange.com/2.3/sites
Defensive patterns
Strategy: try-catch
Validate before calling
// no meaningful pre-call validation; validate parameters instead:
if (!/^[a-z]+$/.test(site)) throw new Error(`invalid site: ${site}`); Try / catch
try {
const data = await seFetch(url);
} catch (e) {
if (/stack exchange API error/.test(e.message)) {
if (/throttl|quota/i.test(e.message)) await sleep(backoff);
else console.error('Fix request params (usually `site`):', e.message);
} else throw e;
} Prevention
- Validate the site name against the /sites endpoint list
- Register an API key to avoid anonymous quota throttling
- Open the request URL in a browser when debugging
- Keep the API version path (2.3) up to date
When it happens
Trigger: Invalid site parameter (site=nonexistent), missing/invalid key with exceeded anonymous quota (error_id=402 throttle_violation), malformed request parameters rejected by the API.
Common situations: Typo'd site name (e.g. site=stackoverflow vs site=stackoverflow needing correct api_site_parameter), anonymous 300-requests-per-day quota exhausted on shared IP, API version path changes.
Related errors
- HTTP_ERROR
- hf models failed: HTTP ${resp.status}
- HTTP ${probe.httpStatus} from Jike users/profile
- Lobsters API HTTP ${res.status} for story ${shortId}
- Stack Exchange API error ${json.error_id} (${json.error_name
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7f1f0d926684560b.
Report an issue: GitHub.