{"record":{"id":"dd8265a4933deafd","repo":"jackwener/OpenCLI","slug":"archive-wayback-returned-malformed-payload-closes","errorCode":null,"errorMessage":"archive wayback returned malformed payload: closest snapshot is missing url/timestamp","messagePattern":"archive wayback returned malformed payload: closest snapshot is missing url/timestamp","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/archive/wayback.js","lineNumber":72,"sourceCode":"        } catch (error) {\n            throw new CommandExecutionError(`archive wayback request failed: ${error?.message || error}`);\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`archive wayback failed: HTTP ${resp.status}`);\n        }\n        let data;\n        try {\n            data = await resp.json();\n        } catch (error) {\n            throw new CommandExecutionError(`archive wayback returned malformed JSON: ${error?.message || error}`);\n        }\n\n        const snap = data?.archived_snapshots?.closest;\n        if (!snap || !snap.available) {\n            throw new EmptyResultError('archive wayback', `No Wayback snapshot for \"${target}\".`);\n        }\n        if (typeof snap.url !== 'string' || !snap.url || !/^\\d{14}$/.test(String(snap.timestamp ?? ''))) {\n            throw new CommandExecutionError('archive wayback returned malformed payload: closest snapshot is missing url/timestamp');\n        }\n\n        return [{\n            original_url: String(data.url ?? target),\n            requested_timestamp: timestamp,\n            snapshot_timestamp: String(snap.timestamp ?? ''),\n            snapshot_url: String(snap.url),\n            status: String(snap.status ?? ''),\n        }];\n    },\n});\n","sourceCodeStart":54,"sourceCodeEnd":84,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/archive/wayback.js#L54-L84","documentation":"A CommandExecutionError thrown when the Wayback snapshot object exists and is marked available but fails shape validation: url is not a non-empty string, or timestamp is not a 14-digit string (e.g. \"20240101120000\"). The library treats this as a malformed API payload rather than an empty result, because the data is present but unusable for building the output row.","triggerScenarios":"`opencli archive wayback <url>` where the closest snapshot has snap.url missing/not a string, or snap.timestamp missing or not matching /^\\d{14}$/ — i.e. the Wayback API response schema deviates from the expected format.","commonSituations":"Wayback API schema changes or A/B rollouts returning new field formats; partially completed save jobs with sparse snapshot objects; unexpected API responses during service incidents.","solutions":["Re-run the command — sparse payloads are often transient during save processing","Log/print the full API response (curl the save endpoint) to inspect the actual snapshot shape","Check whether the archive CLI or Wayback API has been updated (schema drift)","Report/patch: loosen the validation or map the new field format in wayback.js"],"exampleFix":"// before\nif (typeof snap.url !== 'string' || !snap.url || !/^\\d{14}$/.test(String(snap.timestamp ?? ''))) {\n  throw new CommandExecutionError('archive wayback returned malformed payload: ...');\n}\n// after\nconst ts = String(snap.timestamp ?? '');\nif (!snap.url || !/\\d{14}/.test(ts)) {\n  // tolerate ISO timestamps by stripping non-digits before validating\n  if (!/^\\d{14}$/.test(ts.replace(/\\D/g, '').slice(0, 14))) {\n    throw new CommandExecutionError('archive wayback returned malformed payload: closest snapshot is missing url/timestamp');\n  }\n}","handlingStrategy":"type-guard","validationCode":"null","typeGuard":"function isValidSnapshot(snap) {\n  return !!snap && snap.available === true\n    && typeof snap.url === 'string' && snap.url.length > 0\n    && /^\\d{14}$/.test(String(snap.timestamp ?? ''));\n}","tryCatchPattern":"try {\n  return await runWayback(url);\n} catch (e) {\n  if (e.message.includes('malformed payload')) {\n    console.error('Wayback API schema deviation; inspect raw response and retry');\n    await sleep(3000);\n    return runWayback(url); // sparse payloads are often transient\n  }\n  throw e;\n}","preventionTips":["Validate snapshot shape yourself if consuming the raw Wayback API","Retry once — sparse payloads during save processing are usually transient","Track Wayback API schema changes if you depend on this command in CI","Keep the archive CLI updated to pick up parser fixes"],"tags":["schema","validation","archive","wayback"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}