{"record":{"id":"7e2079a3e525396f","repo":"MagicMirrorOrg/MagicMirror","slug":"invalid-api-response","errorCode":null,"errorMessage":"Invalid API response","messagePattern":"Invalid API response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"defaultmodules/weather/providers/buienradar.js","lineNumber":134,"sourceCode":"\t\t\t\tconst data = await response.json();\n\t\t\t\tthis.#handleResponse(data);\n\t\t\t} catch (error) {\n\t\t\t\tLog.error(\"[buienradar] Failed to parse JSON:\", error);\n\t\t\t\tthis.#sendErrorCallback(\"Failed to parse API response\");\n\t\t\t}\n\t\t});\n\n\t\tthis.fetcher.on(\"error\", (errorInfo) => {\n\t\t\tif (this.onErrorCallback) {\n\t\t\t\tthis.onErrorCallback(errorInfo);\n\t\t\t}\n\t\t});\n\t}\n\n\t#handleResponse (data) {\n\t\ttry {\n\t\t\tif (!Array.isArray(data?.days) || data.days.length === 0) {\n\t\t\t\tthrow new Error(\"Invalid API response\");\n\t\t\t}\n\n\t\t\tthis.#setLocationName(data.location);\n\n\t\t\tlet weatherData;\n\t\t\tswitch (this.config.type) {\n\t\t\t\tcase \"current\":\n\t\t\t\t\tweatherData = this.#generateCurrentWeather(data.days[0]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"forecast\":\n\t\t\t\tcase \"daily\":\n\t\t\t\t\tweatherData = this.#generateDailyForecast(data.days);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"hourly\":\n\t\t\t\t\tweatherData = this.#generateHourlyForecast(data.days);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown weather type: ${this.config.type}`);","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/MagicMirrorOrg/MagicMirror/blob/4b4a59534f7da01e4030e46029fe9dd649a7675e/defaultmodules/weather/providers/buienradar.js#L116-L152","documentation":"buienradar's #handleResponse validates the parsed API payload and expects an object with a non-empty `days` array. If the response is shaped differently (missing days, empty array, or non-object), it throws 'Invalid API response'. This guards against unexpected upstream data before processing weather entries.","triggerScenarios":"Buienradar API returns an HTML error page, an error JSON object without a `days` array, or an empty days array; JSON parsing produced something without the expected shape.","commonSituations":"Buienradar service outage or maintenance; network middleware (proxy/captive portal) returning HTML; API schema change; rate limiting returning an error body.","solutions":["Verify the Buienradar endpoint URL is correct and reachable (curl it and inspect the body)","Retry later — often a transient upstream outage","Check this.onErrorCallback logs for the underlying fetch/parse error","Upgrade the module if the Buienradar API schema changed"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const looksLikeBuienradarPayload = (d) => d != null && Array.isArray(d.days) && d.days.length > 0;\nif (!looksLikeBuienradarPayload(data)) console.warn(\"Buienradar payload malformed; will surface provider error\");","typeGuard":"const hasDays = (d) => typeof d === \"object\" && d !== null && Array.isArray(d.days) && d.days.length > 0;","tryCatchPattern":"provider.setCallbacks(\n  (data) => render(data),\n  (err) => { if (err.message === \"Invalid API response\") scheduleRetryWithBackoff(); }\n);","preventionTips":["Monitor buienradar.nl status; expect transient outages","Log raw response bodies on error to detect HTML/proxy interlopers","Pin/review the module version when the upstream API schema changes","Handle the provider's onError callback with a retry/fallback provider"],"tags":["api-response","buienradar","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"4b4a59534f7da01e4030e46029fe9dd649a7675e","analyzedAt":"2026-08-31T21:49:42.591Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}