badges/shields · error · InvalidResponse

unparseable intermediate json response

Error message

unparseable intermediate json response

What it means

getCachedResource in resource-cache.js fetches a resource and, when the json option is set, parses the cached buffer with JSON.parse. If parsing fails it throws InvalidResponse with prettyMessage 'unparseable intermediate json response' — an 'intermediate' resource is data fetched to compute further responses (versions, releases), not the final badge payload.

Source

Thrown at core/base-service/resource-cache.js:51

  options = {},
  requestFetcher = fetch,
}) {
  const timestamp = Date.now()
  const cached = resourceCache[url]
  if (cached != null && timestamp - cached.timestamp < ttl) {
    return cached.data
  }

  const { buffer } = await checkErrorResponse({})(
    await requestFetcher(url, options),
  )

  let reqData
  if (json) {
    try {
      reqData = JSON.parse(buffer)
    } catch (e) {
      throw new InvalidResponse({
        prettyMessage: 'unparseable intermediate json response',
        underlyingError: e,
      })
    }
  } else {
    reqData = buffer
  }

  const data = scraper(reqData)
  resourceCache[url] = { timestamp, data }
  return data
}

function clearResourceCache() {
  resourceCache = Object.create(null)
}

export { getCachedResource, clearResourceCache }

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Clear the affected cache entry (and any local cache directory) so a fresh fetch occurs.
  2. Curl the intermediate resource URL to confirm it returns valid JSON.
  3. Check whether the upstream metadata endpoint moved or changed format.
  4. Verify the fetchLimit didn't truncate the body mid-JSON.
  5. Retry after a transient upstream outage; the cache will then store valid JSON.

Example fix

// before (cached HTML from outage)
reqData = JSON.parse('<html>503...</html>') // throws
// after
cache.clear(key); const reqData = JSON.parse(await refetchBuffer()) // valid JSON
Defensive patterns

Strategy: fallback

Validate before calling

function safeParseJson(buffer) { try { return { ok: true, data: JSON.parse(buffer) } } catch (e) { return { ok: false } } }
if (!safeParseJson(buffer).ok) refreshCacheAndRetry()

Type guard

function isParsedResource(v) { return typeof v === 'object' && v !== null }

Try / catch

try {
  reqData = await getCachedResource({ url, json: true })
} catch (err) {
  if (err.name === 'InvalidResponse') {
    cache.clear(key)
    reqData = await getCachedResource({ url, json: true, skipCache: true })
  } else throw err
}

Prevention

When it happens

Trigger: JSON.parse(buffer) throws while reading a cached/fetched intermediate resource (e.g. getOfferedVersions, getPhpReleases) because the upstream endpoint returned non-JSON content or the cache holds corrupted data.

Common situations: Upstream metadata endpoint (releases/versions list) down and returning HTML, stale or corrupted cache entry written during an earlier partial response, provider API path changed.

Related errors


AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30). Data as JSON: /api/errors/6d286593d636a4ae. Report an issue: GitHub.