crewAIInc/crewAI · error · ProjectDefinitionError
[tool.crewai] definition must resolve inside the project roo
Error message
[tool.crewai] definition must resolve inside the project root; got {definition!r}. What it means
Raised when the resolved candidate path is not inside the resolved project root (is_relative_to fails), i.e. the definition escapes the project via '..' segments or through a symlink that resolves outside the root. This is a path-containment security guard: the crew definition must live within the project. Reported as ProjectDefinitionError with the offending definition value.
Source
Thrown at lib/crewai-core/src/crewai_core/project.py:132
)
try:
root = root_path.resolve(strict=True)
except OSError as exc:
raise ProjectDefinitionError(
f"Invalid project root for [tool.crewai] definition: {exc}"
) from exc
candidate = root / definition_path
try:
resolved_candidate = candidate.resolve(strict=False)
except OSError as exc:
raise ProjectDefinitionError(
f"Invalid [tool.crewai] definition path {definition!r}: {exc}"
) from exc
if not resolved_candidate.is_relative_to(root):
raise ProjectDefinitionError(
"[tool.crewai] definition must resolve inside the project root; "
f"got {definition!r}."
)
if not resolved_candidate.exists():
raise ProjectDefinitionError(
"[tool.crewai] definition must point to an existing file; "
f"got {definition!r}."
)
if not resolved_candidate.is_file():
raise ProjectDefinitionError(
"[tool.crewai] definition must point to a regular file; "
f"got {definition!r}."
)
return resolved_candidate
View on GitHub (pinned to 754d7323be)
Solutions
- Move or copy the definition file inside the project root and reference it with a plain relative path.
- If you need shared code, install it as a package dependency instead of path-hopping out of the project.
- Replace symlinks that point outside the root with real files or a proper package reference.
Example fix
# before [tool.crewai] definition = "../../shared/crew/main.py" # after # move the file into this project, then: [tool.crewai] definition = "src/crew/main.py"
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def stays_inside(definition: str, root: Path) -> bool:
r = root.resolve(strict=True)
c = (r / definition).resolve(strict=False)
return c.is_relative_to(r) Try / catch
except ProjectDefinitionError as e:
if "inside the project root" in str(e):
raise SecurityError(str(e)) from e Prevention
- Never allow '..' segments or out-of-tree symlinks in definition values.
- In monorepos, package shared crew code instead of path-hopping.
When it happens
Trigger: definition = "../../other-project/main.py", or definition = "link/main.py" where link is a symlink to a directory outside the project root; any value whose resolved absolute path is not a prefix-descendant of root.
Common situations: Monorepos where the crew code lives in a sibling package and users try '../../' hops; accidentally committing a symlink to /etc or another checkout; shared crew code referenced across repositories.
Related errors
- Blocked link target escaping destination: {member.name!r} ->
- Invalid skill reference: org and name must be single, non-em
- Blocked path traversal attempt: {member.name!r}
- Blocked path traversal attempt: {member!r}
- Path traversal not allowed: {self.path}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/98a40aa34b8adf6d.
Report an issue: GitHub.