zeroclaw-labs/zeroclaw · error
wttr.in returned HTTP {status} for location '{location}'. Ch
Error message
wttr.in returned HTTP {status} for location '{location}'. Check that the location is valid. What it means
The weather tool calls wttr.in (a free, keyless service) with ?format=j1 and requires a 2xx status; any non-success response bails with the HTTP status and the requested location. wttr.in most commonly returns 404 for unresolvable locations and 503/504 when the service is overloaded or rate-limiting.
Source
Thrown at crates/zeroclaw-tools/src/weather_tool.rs:161
/// Fetch and parse the wttr.in JSON response.
async fn fetch(location: &str) -> anyhow::Result<WttrResponse> {
let url = Self::build_url(location);
let builder = reqwest::Client::builder()
.timeout(Duration::from_secs(WTTR_TIMEOUT_SECS))
.connect_timeout(Duration::from_secs(WTTR_CONNECT_TIMEOUT_SECS))
.user_agent("zeroclaw-weather/1.0");
let builder =
zeroclaw_config::schema::apply_runtime_proxy_to_builder(builder, "tool.weather");
let client = builder.build()?;
let response = client.get(&url).send().await?;
let status = response.status();
if !status.is_success() {
anyhow::bail!(
"wttr.in returned HTTP {status} for location '{location}'. \
Check that the location is valid."
);
}
let body = response.text().await?;
// wttr.in returns a plain-text error string (not JSON) for unknown locations.
if !body.trim_start().starts_with('{') {
anyhow::bail!(
"wttr.in could not resolve location '{location}'. \
Try a city name, airport code, GPS coordinates (lat,lon), or zip code."
);
}
let parsed: WttrResponse = serde_json::from_str(&body).map_err(|e| {
::zeroclaw_log::record!(
WARN,View on GitHub (pinned to 88bb9c8533)
Solutions
- Verify the location string resolves (try it in a browser at wttr.in/<location>) and correct spelling/format
- Retry with exponential backoff and jitter — 5xx and rate-limit responses are transient
- Reduce polling frequency or cache responses; wttr.in data changes at most hourly
- If the outage persists, wait or switch location format (city, IATA code like JFK, 'lat,lon', or zip)
Example fix
// before
{"location":"San Francisko"} // wttr.in returned HTTP 404
// after
{"location":"San Francisco"} Defensive patterns
Strategy: retry
Validate before calling
// Pre-check the location resolves cheaply before polling
// (format guidance: city, IATA code, "lat,lon", zip)
fn plausible_location(loc: &str) -> bool {
!loc.trim().is_empty() && loc.len() < 64
} Try / catch
Err(e) if e.to_string().starts_with("wttr.in returned HTTP") => {
if e.to_string().contains("404") { /* fix location, no retry */ }
else { backoff_and_retry().await /* 5xx/429 are transient */ }
} Prevention
- Cache weather responses for at least an hour
- Add jittered backoff around any free public API
- Normalize locations to canonical forms (city/IATA/lat,lon) before calling
When it happens
Trigger: A misspelled or invented city name (404); sustained polling that trips wttr.in's informal rate limits (429/503); transient outages of the public service (500/502/503/504).
Common situations: Agents polling weather on a schedule; bursts of requests when many sessions start at once (e.g. morning cron storms); a typo like "San Francisko" producing 404 rather than an empty result.
Related errors
- bot info request failed: status={status}, body={body}
- Twitter create tweet failed ({status}): {err}
- Embedding API error {status}: {text}
- Composio v3 API error: {err}
- Composio v3 connected accounts lookup failed: {err}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/243246f8f6b6adc2.
Report an issue: GitHub.