{"record":{"id":"65dea6303a74f7d2","repo":"MemPalace/mempalace","slug":"repair-backup-has-an-invalid-header","errorCode":null,"errorMessage":"repair backup has an invalid header","messagePattern":"repair backup has an invalid header","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mempalace/encoding_repair.py","lineNumber":385,"sourceCode":"    )\n\n\ndef _read_backup_header(\n    path: Path,\n) -> dict:\n    try:\n        with path.open(\n            \"r\",\n            encoding=\"utf-8\",\n        ) as handle:\n            header = json.loads(handle.readline())\n    except OSError as exc:\n        raise ValueError(f\"could not read repair backup: {path}\") from exc\n    except (\n        json.JSONDecodeError,\n        TypeError,\n    ) as exc:\n        raise ValueError(\"repair backup has an invalid header\") from exc\n\n    if not isinstance(\n        header,\n        dict,\n    ) or (header.get(\"format\") != _BACKUP_FORMAT or header.get(\"version\") != _BACKUP_VERSION):\n        raise ValueError(\"unsupported repair backup format\")\n\n    return header\n\n\ndef _iter_backup_records(\n    path: Path,\n) -> Iterator[tuple[str, str]]:\n    _read_backup_header(path)\n\n    with path.open(\n        \"r\",\n        encoding=\"utf-8\",","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/encoding_repair.py#L367-L403","documentation":"Raised by _read_backup_header when the first line of the backup file parses as JSON but fails json.loads with JSONDecodeError, or json.loads receives a non-str (TypeError edge from a decoding quirk). In other words: the file is readable but its header line is not valid JSON, so the backup cannot be trusted. The JSONDecodeError is chained so the exact syntax position is recoverable.","triggerScenarios":"The backup file's first line is truncated (disk full during write, process killed mid-backup), was hand-edited and broke syntax, has a stray BOM or smart quotes, or the file is a different JSON format entirely (pretty-printed multi-line JSON rather than JSONL-with-header).","commonSituations":"Interrupted repair runs (Ctrl-C during backup write) leaving a partial file; editing the backup in a word processor that mangled quotes; concatenating files; disk-full conditions during the original backup creation.","solutions":["Inspect the first line: head -c 300 <backup> — look for truncation, BOM (﻿), or non-ASCII quotes","If the backup is a partial write from an interrupted run, discard it and re-run repair_collection(apply=False) to generate a fresh backup before restoring","If hand-edited, validate: python -c \"import json,sys; json.loads(open(sys.argv[1]).readline())\" <backup>","Re-encode the file as UTF-8 without BOM if a BOM is present"],"exampleFix":"# before: interrupted write left a truncated header\nhead -1 backup.jsonl\n# {\"format\": \"mempalace-encoding-repair\", \"vers\n# after: regenerate the backup\nresult = repair_collection(collection, apply=False)  # writes a fresh, complete backup\n# then restore from result['backup_path']","handlingStrategy":"validation","validationCode":"import json\n\ndef backup_header_parses(path) -> bool:\n    try:\n        json.loads(open(path, encoding='utf-8-sig').readline())\n        return True\n    except (json.JSONDecodeError, UnicodeDecodeError, OSError):\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    restore_backup(collection, backup_path=path)\nexcept ValueError as e:\n    if \"invalid header\" in str(e):\n        sys.exit(f\"Backup header corrupt: {path} — regenerate via repair_collection\")","preventionTips":["Never hand-edit backup files; regenerate instead","Let repair_collection run to completion — interrupted backups are unusable","Ensure sufficient disk space before repairs so backup writes cannot truncate"],"tags":["backup","json","repair","data-integrity"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}