jackwener/OpenCLI · warning · EmptyResultError
${label} returned non-JSON body (likely unknown location).
Error message
${label} returned non-JSON body (likely unknown location). What it means
wttrFetch tries resp.json() on every HTTP 200 response. wttr.in sometimes returns HTTP 200 with a plain-text body (e.g. 'Unknown location') instead of the JSON j1 payload for certain bad inputs, so the JSON parse fails. The library promotes that case to an EmptyResultError rather than surfacing a confusing parse exception, because it almost always means the location string was not recognized.
Source
Thrown at clis/wttr/utils.js:39
let resp;
try {
resp = await fetch(url, { headers: { 'User-Agent': UA, accept: 'application/json' } });
} catch (err) {
throw new CommandExecutionError(`${label} request failed: ${err.message}`);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `${label} could not find location "${location}".`);
}
if (!resp.ok) {
throw new CommandExecutionError(`${label} returned HTTP ${resp.status}.`);
}
let body;
try {
body = await resp.json();
} catch (err) {
// wttr.in falls back to plain-text "Unknown location" for some bad inputs;
// promote that to EmptyResult instead of pretending we got JSON.
throw new EmptyResultError(label, `${label} returned non-JSON body (likely unknown location).`);
}
return body;
}
// wttr.in's "weatherDesc" / "lang_en" fields are arrays of `{ value: '...' }` objects.
// Single-element 99% of the time but the schema is a list.
export function pickWeatherDesc(arr) {
if (!Array.isArray(arr) || !arr.length) return '';
const first = arr[0];
return typeof first?.value === 'string' ? first.value.trim() : '';
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the location string — correct spelling, use 'City,Country' format or a known airport code (e.g. 'LHR').
- Try a lat,lon pair (e.g. '48.85,2.35') if the name keeps failing.
- Test the same URL in a browser (https://wttr.in/<location>?format=j1) to see the raw response.
- URL-encode or strip special characters from the location before passing it.
Example fix
// before
await wttrFetch('Nowhereville XYZ', 'weather');
// after
await wttrFetch('Berlin,Germany', 'weather'); // or '52.52,13.40' Defensive patterns
Strategy: validation
Validate before calling
function isPlausibleLocation(loc) {
return typeof loc === 'string' && loc.trim().length > 1 && !/[\u0000-\u001f]/.test(loc);
}
if (!isPlausibleLocation(userInput)) throw new Error('Provide a real city, airport code, or lat,lon'); Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
const weather = await body('--location', loc);
} catch (err) {
if (/non-JSON body/.test(err.message)) {
console.error(`Unknown location "${loc}" — try 'City,Country' or a lat,lon pair`);
} else throw err;
} Prevention
- Prefer unambiguous inputs: 'City,Country' or ISO airport codes or 'lat,lon'.
- Trim and normalize user-provided location strings before calling.
- Keep a known-good fallback location to smoke-test connectivity vs. bad input.
- Verify unfamiliar location strings once in a browser against wttr.in.
When it happens
Trigger: Calling wttrFetch with a location string wttr.in cannot geocode (gibberish, empty-ish, or specially malformed input) such that wttr.in replies 200 with a non-JSON plain-text body.
Common situations: Passing a misspelled or invented place name that isn't caught by the 404 path; passing control characters or odd encodings; wttr.in changing its fallback behavior for unknown locations from 404 to text-200.
Related errors
- No prices returned for train_no=${trainNo} ${fromStation.nam
- No 12306 stations match "${keyword}"
- No trains found from ${fromStation.name} to ${toStation.name
- 1point3acres thread
- 1point3acres user
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/70750af00a878c90.
Report an issue: GitHub.