moeru-ai/airi · error · Error

Weather request failed: ${res.status}

Error message

Weather request failed: ${res.status}

What it means

Thrown by fetchWeather when the Open-Meteo forecast endpoint responds non-ok after geocoding already succeeded. The status code is embedded. Coordinates were valid (geocode worked), but the forecast query failed.

Source

Thrown at apps/stage-tamagotchi/src/renderer/stores/tools/builtin/weather-api.ts:125

  const result = data.results[0]
  return { name: result.name, latitude: result.latitude, longitude: result.longitude, country: result.country }
}

export async function fetchWeather(city: string): Promise<WeatherData> {
  const geo = await geocodeCity(city)

  const params = new URLSearchParams({
    latitude: String(geo.latitude),
    longitude: String(geo.longitude),
    current: 'temperature_2m,relative_humidity_2m,apparent_temperature,weather_code,wind_speed_10m,precipitation,is_day',
    daily: 'temperature_2m_max,temperature_2m_min',
    forecast_days: '1',
  })

  const res = await fetch(`https://api.open-meteo.com/v1/forecast?${params}`)

  if (!res.ok)
    throw new Error(`Weather request failed: ${res.status}`)

  const data: OpenMeteoWeather = await res.json()
  const current = data.current
  const isNight = current.is_day === 0
  const { conditionCode, condition } = mapWmoCode(current.weather_code, isNight)

  return {
    city: geo.name,
    country: geo.country,
    temperature: `${Math.round(current.temperature_2m)}°C`,
    condition,
    conditionCode,
    isNight,
    feelsLike: `${Math.round(current.apparent_temperature)}°C`,
    humidity: `${current.relative_humidity_2m}%`,
    wind: `${Math.round(current.wind_speed_10m)} km/h`,
    precipitation: `${current.precipitation} mm`,
    high: data.daily ? `${Math.round(data.daily.temperature_2m_max[0])}°C` : undefined,

View on GitHub (pinned to 27111382b4)

Solutions

  1. Retry the forecast call — 5xx/429 are transient.
  2. Verify the URLSearchParams current/daily field names match the current Open-Meteo schema.
  3. Check the Open-Meteo status page.
  4. Cache geocode results so a forecast retry doesn't re-pay geocoding.
Defensive patterns

Strategy: retry

Try / catch

async function fetchWeatherWithRetry(city: string, attempts = 2) {
  for (let i = 0; i < attempts; i++) {
    try { return await fetchWeather(city) }
    catch (e) {
      const msg = e instanceof Error ? e.message : ''
      if (msg.startsWith('Weather request failed') && i < attempts - 1) {
        await new Promise(r => setTimeout(r, 800)); continue
      }
      throw e
    }
  }
  throw new Error('unreachable')
}

Prevention

When it happens

Trigger: Open-Meteo forecast API returned 4xx/5xx — rate limited (429), service incident (5xx), malformed query params (e.g. unsupported variable name), or proxy error. Distinct from [56] which is the geocoding step.

Common situations: Transient outage of the forecast endpoint specifically; rate limiting after many weather calls; URLSearchParams included an unsupported field; network blip between geocode and forecast.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/6dba29f15ca25c1b. Report an issue: GitHub.