{"record":{"id":"d93bc8ea8f33442e","repo":"github/spec-kit","slug":"integration-manifest-at-path-is-not-valid-utf-8","errorCode":null,"errorMessage":"Integration manifest at {path} is not valid UTF-8","messagePattern":"Integration manifest at (.+?) is not valid UTF-8","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/integrations/manifest.py","lineNumber":474,"sourceCode":"\n    @classmethod\n    def load(\n        cls,\n        key: str,\n        project_root: Path,\n        *,\n        resolve_project_root: bool = True,\n    ) -> IntegrationManifest:\n        \"\"\"Load an existing manifest from disk.\n\n        Raises ``FileNotFoundError`` if the manifest does not exist.\n        \"\"\"\n        inst = cls(key, project_root, resolve_project_root=resolve_project_root)\n        path = inst.manifest_path\n        try:\n            data = json.loads(path.read_text(encoding=\"utf-8\"))\n        except UnicodeDecodeError as exc:\n            raise ValueError(\n                f\"Integration manifest at {path} is not valid UTF-8\"\n            ) from exc\n        except json.JSONDecodeError as exc:\n            raise ValueError(\n                f\"Integration manifest at {path} contains invalid JSON\"\n            ) from exc\n\n        if not isinstance(data, dict):\n            raise ValueError(\n                f\"Integration manifest at {path} must be a JSON object, \"\n                f\"got {type(data).__name__}\"\n            )\n\n        files = data.get(\"files\", {})\n        if not isinstance(files, dict) or not all(\n            isinstance(k, str) and isinstance(v, str) for k, v in files.items()\n        ):\n            raise ValueError(","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/integrations/manifest.py#L456-L492","documentation":"IntegrationManifest.load() read the manifest JSON file but decoding as UTF-8 failed. The manifest format is UTF-8 JSON by contract; a non-UTF-8 file is treated as corruption rather than guessed at.","triggerScenarios":"IntegrationManifest.load(key, root) where .specify/integrations/<key>.manifest.json contains bytes invalid in UTF-8 — e.g. written by a tool in Latin-1/GBK encoding, or truncated/corrupted by a bad merge or disk issue.","commonSituations":"Editors or scripts on Windows saving with a legacy codepage; git merge conflicts resolved with markers left in; binary corruption from interrupted writes or sync tools.","solutions":["Inspect the file: file .specify/integrations/<key>.manifest.json and cat -v it for garbage","Restore from git history if tracked (git checkout -- <path>) or delete it and re-run specify integration install <key> to regenerate","If hand-edited, re-save explicitly as UTF-8"],"exampleFix":"# before (Latin-1 bytes in the file)\n# after\ndel .specify/integrations/claude.manifest.json\nspecify integration install claude  # regenerates a clean UTF-8 manifest","handlingStrategy":"validation","validationCode":"raw = manifest.manifest_path.read_bytes()\ntry:\n    raw.decode(\"utf-8\")\nexcept UnicodeDecodeError:\n    manifest.manifest_path.unlink()  # corrupt; regenerate","typeGuard":null,"tryCatchPattern":"try:\n    IntegrationManifest.load(key, root)\nexcept ValueError as exc:\n    if \"not valid UTF-8\" in str(exc):\n        regenerate_manifest(key, root)  # delete + re-install\n    else:\n        raise","preventionTips":["Save hand-edits as UTF-8","Commit .specify to git so corruption is recoverable","Avoid tools that rewrite files in legacy codepages"],"tags":["manifest","encoding","corruption"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}