glanceapp/glance · error
%w: %v
Error message
%w: %v
What it means
The forecast fetch for a resolved place failed: decodeJsonFromRequest against api.open-meteo.com/v1/forecast returned an error (transport failure or non-200), wrapped as errNoContent so the widget shows its no-content state.
Source
Thrown at internal/glance/widget-weather.go:237
} else {
temperatureUnit = "celsius"
}
query.Add("latitude", fmt.Sprintf("%f", place.Latitude))
query.Add("longitude", fmt.Sprintf("%f", place.Longitude))
query.Add("timeformat", "unixtime")
query.Add("timezone", place.Timezone)
query.Add("forecast_days", "1")
query.Add("current", "temperature_2m,apparent_temperature,weather_code")
query.Add("hourly", "temperature_2m,precipitation_probability")
query.Add("daily", "sunrise,sunset")
query.Add("temperature_unit", temperatureUnit)
requestUrl := "https://api.open-meteo.com/v1/forecast?" + query.Encode()
request, _ := http.NewRequest("GET", requestUrl, nil)
responseJson, err := decodeJsonFromRequest[openMeteoWeatherResponseJson](defaultHTTPClient, request)
if err != nil {
return nil, fmt.Errorf("%w: %v", errNoContent, err)
}
now := time.Now().In(place.location)
bars := make([]weatherColumn, 0, 24)
currentBar := now.Hour() / 2
sunriseBar := (time.Unix(int64(responseJson.Daily.Sunrise[0]), 0).In(place.location).Hour()) / 2
sunsetBar := (time.Unix(int64(responseJson.Daily.Sunset[0]), 0).In(place.location).Hour() - 1) / 2
if sunsetBar < 0 {
sunsetBar = 0
}
if len(responseJson.Hourly.Temperature) == 24 {
temperatures := make([]int, 12)
precipitations := make([]bool, 12)
t := responseJson.Hourly.Temperature
p := responseJson.Hourly.PrecipitationProbabilityView on GitHub (pinned to 91324e8de7)
Solutions
- Inspect the nested %v — a 429 with 'API key' context means you exceeded the free tier and should cache longer or supply a paid key where supported
- Raise the weather widget's cache duration (it already caches on the hour by default) and avoid hard-refresh storms
- Verify connectivity from the host to api.open-meteo.com and retry after transient 5xx
Defensive patterns
Strategy: retry
Type guard
func isNoContent(err error) bool { return errors.Is(err, errNoContent) } Try / catch
w, err := fetchWeatherForOpenMeteoPlace(place, units)
if errors.Is(err, errNoContent) {
// transient forecast fetch failure: keep last good data or retry after backoff
slog.Warn("weather fetch failed", "err", err)
return lastGoodWeather
} Prevention
- Cache weather results — the widget already caches on the hour; avoid shorter overrides on rate-limited deployments
- Check errors.Is(err, errNoContent) and degrade to a cached/stale forecast instead of an error page
- Watch the nested cause to distinguish 429 (back off) from network outage (retry later)
When it happens
Trigger: GET https://api.open-meteo.com/v1/forecast?... returning 429 (Open-Meteo free-tier rate limit), 5xx, or the request failing at the network layer from the Glance host.
Common situations: Frequent page loads with short cache hitting Open-Meteo's per-day request quota; transient upstream outage; blocked egress from a containerized deployment.
Related errors
- fetching places data: %v
- could not solve reddit challenge
- unexpected status code %d from %s, response: %s
- no places found for %s
- no place found for %s in %s
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/1fb53e5783ed72fe.
Report an issue: GitHub.