{"record":{"id":"ec3394c715ae0a0a","repo":"crewAIInc/crewAI","slug":"invalid-project-root-for-tool-crewai-definition","errorCode":null,"errorMessage":"Invalid project root for [tool.crewai] definition: {exc}","messagePattern":"Invalid project root for \\[tool\\.crewai\\] definition: (.+?)","errorType":"exception","errorClass":"ProjectDefinitionError","httpStatus":null,"severity":"error","filePath":"lib/crewai-core/src/crewai_core/project.py","lineNumber":119,"sourceCode":"    definition_path = Path(definition)\n    windows_definition_path = PureWindowsPath(definition)\n\n    if definition.startswith(\"~\"):\n        raise ProjectDefinitionError(\n            \"[tool.crewai] definition must be a project-local path; \"\n            f\"got {definition!r}.\"\n        )\n\n    if definition_path.is_absolute() or windows_definition_path.is_absolute():\n        raise ProjectDefinitionError(\n            \"[tool.crewai] definition must be relative to the project root; \"\n            f\"got {definition!r}.\"\n        )\n\n    try:\n        root = root_path.resolve(strict=True)\n    except OSError as exc:\n        raise ProjectDefinitionError(\n            f\"Invalid project root for [tool.crewai] definition: {exc}\"\n        ) from exc\n\n    candidate = root / definition_path\n    try:\n        resolved_candidate = candidate.resolve(strict=False)\n    except OSError as exc:\n        raise ProjectDefinitionError(\n            f\"Invalid [tool.crewai] definition path {definition!r}: {exc}\"\n        ) from exc\n\n    if not resolved_candidate.is_relative_to(root):\n        raise ProjectDefinitionError(\n            \"[tool.crewai] definition must resolve inside the project root; \"\n            f\"got {definition!r}.\"\n        )\n\n    if not resolved_candidate.exists():","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-core/src/crewai_core/project.py#L101-L137","documentation":"Raised when Path.resolve(strict=True) on the project root raises OSError, meaning the root passed to resolve_project_definition_path does not exist or cannot be stat'd (missing directory, permission denied, broken symlink, or a path component that is a file). The definition path itself has not been evaluated yet; the problem is the root. The original OSError is chained via 'from exc'.","triggerScenarios":"Calling resolve_project_definition_path(definition=\"main.py\", project_root=\"/nonexistent/dir\") or with a root the process cannot read; also when the root contains a symlink loop or the passed root is actually a file path.","commonSituations":"Hardcoding a root in CI that differs between runners, running from a deleted/renamed working directory, or passing repo-root detection output (e.g. git rev-parse) that returned empty and got joined into an invalid path.","solutions":["Check the project root exists and is a directory before calling the resolver: Path(project_root).is_dir().","Print or log the exact root value being passed; it usually differs from what you expect in CI or when cwd changed.","Derive the root from a known anchor (the pyproject.toml location) instead of assuming cwd."],"exampleFix":"# before\nroot = os.environ.get(\"CREW_ROOT\", \"/opt/crew\")  # may not exist\npath = resolve_project_definition_path(definition, root)\n\n# after\nroot = Path(__file__).resolve().parent.parent  # anchor to this file\npath = resolve_project_definition_path(definition, root)","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef valid_root(project_root: str | Path) -> bool:\n    p = Path(project_root)\n    return p.exists() and p.is_dir() and p.resolve(strict=True) is not None","typeGuard":null,"tryCatchPattern":"try:\n    path = resolve_project_definition_path(definition, root)\nexcept ProjectDefinitionError as e:\n    if \"Invalid project root\" in str(e):\n        # root problem, not definition problem\n        ...","preventionTips":["Derive project_root from an anchor file (pyproject.toml location) rather than cwd or env vars.","Assert the root directory exists at startup, not lazily at first resolution."],"tags":["filesystem","environment","path-resolution"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}