{"record":{"id":"0a2b689a00797673","repo":"MagicMirrorOrg/MagicMirror","slug":"failed-to-fetch-observation-stations-http-stati","errorCode":null,"errorMessage":"Failed to fetch observation stations: HTTP ${stationsResponse.status}","messagePattern":"Failed to fetch observation stations: HTTP (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"defaultmodules/weather/providers/weathergov.js","lineNumber":163,"sourceCode":"\t\t\t}\n\n\t\t\t// Store forecast URLs\n\t\t\tthis.forecastURL = `${pointsData.properties.forecast}?units=si`;\n\t\t\tthis.forecastHourlyURL = `${pointsData.properties.forecastHourly}?units=si`;\n\t\t\tthis.forecastGridDataURL = pointsData.properties.forecastGridData;\n\t\t\tthis.observationStationsURL = pointsData.properties.observationStations;\n\n\t\t\t// Step 2: Get observation station URL\n\t\t\tconst stationsResponse = await fetch(this.observationStationsURL, {\n\t\t\t\tsignal: controller.signal,\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": \"MagicMirror\",\n\t\t\t\t\tAccept: \"application/geo+json\"\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!stationsResponse.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch observation stations: HTTP ${stationsResponse.status}`);\n\t\t\t}\n\n\t\t\tconst stationsData = await stationsResponse.json();\n\n\t\t\tif (!stationsData || !stationsData.features || stationsData.features.length === 0) {\n\t\t\t\tthrow new Error(\"No observation stations found\");\n\t\t\t}\n\n\t\t\tthis.stationObsURL = `${stationsData.features[0].id}/observations/latest`;\n\n\t\t\tLog.log(`[weathergov] Initialized for ${this.locationName}`);\n\t\t} finally {\n\t\t\tclearTimeout(timeoutId);\n\t\t}\n\t}\n\n\t#initializeFetcher () {\n\t\tlet url;","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/MagicMirrorOrg/MagicMirror/blob/4b4a59534f7da01e4030e46029fe9dd649a7675e/defaultmodules/weather/providers/weathergov.js#L145-L181","documentation":"To find the nearest observation station, #fetchWeatherGovURLs fetches the stations collection for the grid point. A non-ok HTTP status (embedded in the message) aborts initialization with this Error.","triggerScenarios":"GET to the grid point's stations endpoint returns 404 (grid point has no station list), 429/503 (rate limit or NWS outage), or any other non-ok status.","commonSituations":"NWS API rate limiting after frequent polling (MagicMirror's default interval); api.weather.gov incidents; requesting stations for remote/ocean grid points with sparse coverage.","solutions":["Check the status: 429/503 means rate limited or down — increase the updateInterval and retry later.","Verify api.weather.gov health at status.weather.gov for 5xx errors.","Reduce polling frequency so you stay under NWS rate limits (user-agent identified clients are expected to poll sparingly).","If only current-weather observation fails, consider type \"forecast\"/\"daily\" which does not need stations."],"exampleFix":"// before\nconfig: { weatherProvider: \"weathergov\", type: \"current\", updateInterval: 60000 } // too aggressive\n// after\nconfig: { weatherProvider: \"weathergov\", type: \"current\", updateInterval: 600000 }","handlingStrategy":"retry","validationCode":"// verify the stations endpoint before enabling type \"current\"\nconst r = await fetch(`${forecastGridpoint}/stations`, { headers: { \"User-Agent\": \"MagicMirror\" } });\nif (!r.ok) throw new Error(`stations pre-flight failed: HTTP ${r.status}`);","typeGuard":null,"tryCatchPattern":"async function initWithRetry(provider, tries = 3) {\n  for (let i = 0; i < tries; i++) {\n    try { await provider.initialize(); return; }\n    catch (err) {\n      const m = err.message.match(/HTTP (\\d+)/);\n      const retryable = m && (m[1].startsWith(\"5\") || m[1] === \"429\");\n      if (!retryable || i === tries - 1) throw err;\n      await new Promise(r => setTimeout(r, 2 ** i * 30_000));\n    }\n  }\n}","preventionTips":["Set updateInterval >= 10 minutes; NWS asks clients not to poll aggressively.","Back off exponentially on 429/5xx instead of failing hard.","Use type \"forecast\" when station availability is not essential."],"tags":["network","http","weather","rate-limit"],"backgroundTag":"http-request-failed","analyzedSha":"4b4a59534f7da01e4030e46029fe9dd649a7675e","analyzedAt":"2026-08-31T21:49:42.591Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}