{"record":{"id":"0969d98c99cb8333","repo":"github/spec-kit","slug":"corrupt-records-file-path","errorCode":null,"errorMessage":"Corrupt records file: {path}","messagePattern":"Corrupt records file: (.+?)","errorType":"exception","errorClass":"BundlerError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/bundler/models/records.py","lineNumber":127,"sourceCode":"    seen = str(value).strip()\n    if seen.split(\".\")[0] != RECORDS_SCHEMA_VERSION.split(\".\")[0]:\n        raise BundlerError(\n            f\"Unsupported records schema version '{seen}' at {path}; this \"\n            f\"Spec Kit understands version {RECORDS_SCHEMA_VERSION}. The file may \"\n            \"have been written by a newer version or is corrupt.\"\n        )\n\n\ndef load_records(project_root: Path) -> list[InstalledBundleRecord]:\n    # Defense in depth (mirrors the write path's within= confinement): refuse to\n    # read through a symlinked or traversal-escaping ``.specify`` that resolves\n    # outside project_root.\n    path = ensure_within(project_root, records_path(project_root))\n    if not path.exists():\n        return []\n    data = load_json(path)\n    if not isinstance(data, dict):\n        raise BundlerError(f\"Corrupt records file: {path}\")\n    _check_schema_version(data.get(\"schema_version\"), path=path, required=True)\n    bundles = data.get(\"bundles\")\n    if bundles is None:\n        bundles = []\n    elif not isinstance(bundles, list):\n        # `or []` would coerce a FALSY non-list (0, '', False, {}) to [] before\n        # this guard, silently treating a corrupt file as \"no bundles\"; only an\n        # absent/None value means empty.\n        raise BundlerError(\n            f\"Corrupt records file: {path} — 'bundles' must be a list.\"\n        )\n    return [InstalledBundleRecord.from_dict(item) for item in bundles]\n\n\ndef save_records(project_root: Path, records: list[InstalledBundleRecord]) -> None:\n    payload = {\n        \"schema_version\": RECORDS_SCHEMA_VERSION,\n        \"updated_at\": _utc_now(),","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/bundler/models/records.py#L109-L145","documentation":"Raised by load_records when the installed-bundles records file parses to a non-object JSON value at the top level (e.g. an array or bare string). The reader needs a mapping to extract 'schema_version' and 'bundles'; anything else is treated as corruption with the path in the message. Note the read path is also confined via ensure_within, refusing symlinked or traversal-escaping .specify paths.","triggerScenarios":"load_records(project_root) finds the records path exists, load_json returns a list/scalar, and the isinstance(data, dict) guard raises before schema-version checking.","commonSituations":"A records file overwritten with a JSON array of records (dropping the wrapper object); truncation/corruption after a crash; editing in a tool that reformatted the whole document.","solutions":["Wrap the content in a top-level object: {\"schema_version\": \"1\", \"bundles\": [...]}.","If content integrity is doubtful, delete the file and reinstall bundles — load_records returns [] for a missing file.","Check for symlinks under .specify pointing outside the project if the path in the message looks unexpected."],"exampleFix":"// before (installed-bundles.json)\n[\n  {\"bundle_id\": \"my-bundle\", \"version\": \"1.0.0\"}\n]\n\n// after\n{\n  \"schema_version\": \"1\",\n  \"bundles\": [\n    {\"bundle_id\": \"my-bundle\", \"version\": \"1.0.0\"}\n  ]\n}","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\ndef records_is_object(path: Path) -> bool:\n    return isinstance(json.loads(path.read_text()), dict)","typeGuard":"def is_records_object(data: object) -> bool:\n    return isinstance(data, dict)","tryCatchPattern":"try:\n    records = load_records(project_root)\nexcept BundlerError as e:\n    if \"Corrupt records file\" in str(e):\n        # back up the file, then either repair to {schema_version, bundles} or\n        # delete it and reinstall bundles to rebuild state\n        ...","preventionTips":["The records file's top level is an object with schema_version and bundles keys.","Avoid editors/formatters that might rewrite the whole document into an array.","Restore .specify state from version control rather than editing by hand."],"tags":["bundler","records","json","validation","corruption"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}