{"record":{"id":"dac774bc0a57d640","repo":"jackwener/OpenCLI","slug":"archive-search-returned-malformed-payload-for-i","errorCode":null,"errorMessage":"archive search returned malformed payload for \"${id}\": downloads must be numeric","messagePattern":"archive search returned malformed payload for \"(.+?)\": downloads must be numeric","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/archive/search.js","lineNumber":100,"sourceCode":"            throw new CommandExecutionError(`archive search returned malformed JSON: ${error?.message || error}`);\n        }\n\n        const docs = data?.response?.docs;\n        if (!Array.isArray(docs)) {\n            throw new CommandExecutionError('archive search returned malformed payload: response.docs must be an array');\n        }\n        if (docs.length === 0) {\n            throw new EmptyResultError('archive search', `No items match \"${query}\" on archive.org.`);\n        }\n\n        return docs.slice(0, limit).map((d, i) => {\n            const id = String(d.identifier ?? '');\n            if (!IDENTIFIER_RE.test(id)) {\n                throw new CommandExecutionError('archive search returned malformed payload: result row is missing a stable identifier');\n            }\n            const downloads = Number(d.downloads ?? 0);\n            if (!Number.isFinite(downloads)) {\n                throw new CommandExecutionError(`archive search returned malformed payload for \"${id}\": downloads must be numeric`);\n            }\n            const creator = Array.isArray(d.creator) ? d.creator.join(', ') : String(d.creator ?? '');\n            return {\n                rank: i + 1,\n                identifier: id,\n                title: String(d.title ?? ''),\n                creator,\n                date: d.date ? String(d.date).slice(0, 10) : '',\n                mediatype: String(d.mediatype ?? ''),\n                downloads,\n                url: id ? `https://archive.org/details/${id}` : '',\n            };\n        });\n    },\n});\n","sourceCodeStart":82,"sourceCodeEnd":116,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/archive/search.js#L82-L116","documentation":"CommandExecutionError thrown in `opencli archive search` when a result row's `downloads` field, after `Number(d.downloads ?? 0)`, is not finite (e.g. a non-numeric string). The library coerces missing downloads to 0 but refuses rows where the value exists yet is not numeric, since ranking output would be corrupted.","triggerScenarios":"A docs row contains downloads as a non-numeric value (object, weird string) so Number.isFinite(Number(...)) is false; the row already passed the identifier check, so the error message carries that identifier.","commonSituations":"archive.org returning inconsistent field types across rows; schema drift in the search API; cached/proxied responses with altered field values.","solutions":["Re-run the query — this is often transient bad data from archive.org.","Inspect the offending row via https://archive.org/advancedsearch.php with the same query to confirm the downloads value's type.","Narrow the query to avoid the problematic item if one specific row is corrupt.","Report the malformed row upstream if it persists."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check downloads field type on the raw payload before invoking the CLI mapping\nconst bad = docs.filter(d => {\n  const n = Number(d.downloads ?? 0);\n  return !Number.isFinite(n);\n});\nif (bad.length) console.warn(`rows with non-numeric downloads: ${bad.map(b => b.identifier)}`);","typeGuard":"function hasNumericDownloads(row) {\n  return Number.isFinite(Number(row?.downloads ?? 0));\n}","tryCatchPattern":"try {\n  const rows = await run(['archive', 'search', query]);\n} catch (e) {\n  if (/downloads must be numeric/.test(e.message)) {\n    const id = e.message.match(/for \"([^\"]+)\"/)?.[1];\n    console.warn(`bad downloads value for item ${id}; refetching or skipping`);\n  } else throw e;\n}","preventionTips":["Re-query on this error — it is usually transient bad data.","Validate raw payloads in tests with recorded fixtures.","Watch for archive.org API schema-change announcements."],"tags":["malformed-payload","type-error","archive-org","data-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}