{"record":{"id":"d7f196220f98ab88","repo":"github/spec-kit","slug":"manifest-project-root-manifest-project-root-do-d7f196","errorCode":null,"errorMessage":"manifest.project_root ({manifest.project_root}) does not match project_root ({project_root_resolved})","messagePattern":"manifest\\.project_root \\((.+?)\\) does not match project_root \\((.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/integrations/copilot/__init__.py","lineNumber":493,"sourceCode":"\n        # Install agent runtime events\n        event_files = self.emit_events(\n            project_root, manifest, events=opts.get(\"events\"), parsed_options=parsed_options\n        )\n        created.extend(event_files)\n        return created\n\n    def _setup_commands(\n        self,\n        project_root: Path,\n        manifest: IntegrationManifest,\n        parsed_options: dict[str, Any] | None = None,\n        **opts: Any,\n    ) -> list[Path]:\n        \"\"\"Commands mode: .agent.md + .prompt.md + VS Code settings merge.\"\"\"\n        project_root_resolved = project_root.resolve()\n        if manifest.project_root != project_root_resolved:\n            raise ValueError(\n                f\"manifest.project_root ({manifest.project_root}) does not match \"\n                f\"project_root ({project_root_resolved})\"\n            )\n\n        templates = self.list_command_templates()\n        if not templates:\n            return []\n\n        from ...presets import PresetResolver\n\n        preset_resolver = PresetResolver(project_root_resolved)\n\n        dest = self.commands_dest(project_root)\n        dest_resolved = dest.resolve()\n        try:\n            dest_resolved.relative_to(project_root_resolved)\n        except ValueError as exc:\n            raise ValueError(","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/integrations/copilot/__init__.py#L475-L511","documentation":"Raised by CopilotIntegration._setup_commands() (src/specify_cli/integrations/copilot/__init__.py:493) when the IntegrationManifest passed to setup() was constructed against a different project root than the one given to the call (compared after Path.resolve()). The manifest records project_root at creation, and every setup path verifies the caller is still operating in that same project to prevent cross-project writes.","triggerScenarios":"Calling integration.setup(project_root, manifest) with a manifest built via IntegrationManifest(other_root) — e.g. manifest created for the resolved cwd but setup invoked with a symlinked or differently-spelled path, or a manifest reused across two projects.","commonSituations":"Programmatically driving setup() and creating the manifest in one directory then calling setup with another; macOS /tmp vs /private/tmp symlink mismatches after resolve(); reusing a cached manifest object after the process changed directories.","solutions":["Construct the IntegrationManifest with the exact same project_root (resolved the same way) that you pass to setup().","Use project_root.resolve() consistently at both construction and call sites.","Do not reuse a manifest across projects — create a fresh manifest per project.","If invoking the CLI, re-run 'specify init' from the project directory instead of calling setup() manually."],"exampleFix":"# before\nmanifest = IntegrationManifest(project_root=Path(\"/tmp/proj\"))\nintegration.setup(Path(\"/private/tmp/proj\"), manifest)\n\n# after\nroot = Path(\"/tmp/proj\").resolve()\nmanifest = IntegrationManifest(project_root=root)\nintegration.setup(root, manifest)","handlingStrategy":"validation","validationCode":"root = project_root.resolve()\nassert manifest.project_root == root, (\n    f\"manifest {manifest.project_root} != root {root}\"\n)","typeGuard":null,"tryCatchPattern":"try:\n    integration.setup(root, manifest)\nexcept ValueError as e:\n    if \"does not match\" in str(e):\n        manifest = IntegrationManifest(project_root=root.resolve())\n        integration.setup(root, manifest)\n    else:\n        raise","preventionTips":["Always create IntegrationManifest with project_root.resolve().","Reuse one resolved Path variable for both manifest construction and setup().","Never share a manifest between projects.","Prefer the specify CLI over manual setup() calls."],"tags":["filesystem","paths","integration-setup","spec-kit","copilot"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}