{"record":{"id":"6a8ebf3fc73bf0b2","repo":"ellite/Wallos","slug":"invalid-json-response","errorCode":null,"errorMessage":"Invalid JSON response","messagePattern":"Invalid JSON response","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/subscriptions.js","lineNumber":463,"sourceCode":"  });\r\n}\r\n\r\nfunction fetchLogoSearchSource(url, retry = true) {\r\n  return fetch(url, {\r\n    cache: \"no-store\",\r\n    headers: { \"Accept\": \"application/json\" },\r\n  })\r\n    .then(response => {\r\n      if (!response.ok) {\r\n        throw new Error(`HTTP ${response.status}`);\r\n      }\r\n      return response.text();\r\n    })\r\n    .then(body => {\r\n      try {\r\n        return JSON.parse(body);\r\n      } catch (error) {\r\n        throw new Error(\"Invalid JSON response\");\r\n      }\r\n    })\r\n    .catch(error => {\r\n      if (retry) {\r\n        // Wait a moment before retrying: sources like Brave rate-limit\r\n        // aggressively, and retrying instantly just repeats the failure.\r\n        return new Promise(resolve => setTimeout(resolve, 600))\r\n          .then(() => fetchLogoSearchSource(url, false));\r\n      }\r\n      throw error;\r\n    });\r\n}\r\n\r\nfunction displayImageResults(imageSources, container) {\r\n  container.innerHTML = \"\";\r\n\r\n  imageSources.forEach(src => {\r\n    const img = document.createElement(\"img\");\r","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/ellite/Wallos/blob/52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd/scripts/subscriptions.js#L445-L481","documentation":"In the same helper, after a successful HTTP response the body is read as text and JSON.parse'd; a parse failure throws 'Invalid JSON response'. The server returned 2xx but the body is not valid JSON — commonly an HTML interstitial, empty body, or garbled/encoding-broken payload. The helper's catch block may retry the request once for transient cases.","triggerScenarios":"response.text() yields non-JSON content despite 2xx: an HTML page served with 200 (captive portal, wrong URL, consent wall), empty response body, truncated or encoding-corrupted JSON, or the provider sending plain text/CSV where JSON was expected.","commonSituations":"Proxies or firewalls injecting HTML into 200 responses; provider quietly changing its response format; intermittent network truncation (mitigated by the helper's built-in retry); Accept header not honored so the server returns HTML.","solutions":["Log responseText before parsing to see exactly what was returned on a 200.","Check whether the body is HTML (login/consent/proxy page) and address the redirect/auth issue at that layer.","Ensure the request sends Accept: application/json (this helper already does) and that the provider supports JSON output.","If the format changed, update the parsing logic to match the provider's current schema.","For intermittent truncation, keep the existing retry but add a small delay/backoff."],"exampleFix":"// before\ntry {\n  return JSON.parse(body);\n} catch (error) {\n  throw new Error(\"Invalid JSON response\");\n}\n// after\ntry {\n  return JSON.parse(body);\n} catch (error) {\n  throw new Error(`Invalid JSON response: ${body.slice(0, 120)}`);\n}","handlingStrategy":"retry","validationCode":"function isLikelyJson(text) {\n  const t = (text ?? '').trim();\n  return t.length > 0 && !/^\\s*<!doctype html/i.test(t) && (t.startsWith('{') || t.startsWith('['));\n}","typeGuard":null,"tryCatchPattern":"fetchSourceData(url).catch(err => {\n  if (err.message === 'Invalid JSON response') {\n    return fetchSourceData(url, /* retry */ true); // helper retries once; add backoff\n  }\n  throw err;\n});","preventionTips":["Send Accept: application/json on every source request and confirm the provider honors it.","Log response bodies (truncated) when parse fails to detect HTML injection or format changes.","Handle transient truncation with a single delayed retry (the helper already supports this).","Monitor providers for response-format changes and pin/adapter your parser accordingly."],"tags":["network","json","api","javascript"],"backgroundTag":"invalid-json-response","analyzedSha":"52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd","analyzedAt":"2026-09-13T14:09:30.873Z","contentChangedAt":"2026-09-13T14:09:30.873Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}