Skip to content

fix: resolve agent/crew skills paths against project_root, not cwd#6596

Open
MedviJenka wants to merge 1 commit into
crewAIInc:mainfrom
MedviJenka:fix/skills-resolve-relative-to-project-root
Open

fix: resolve agent/crew skills paths against project_root, not cwd#6596
MedviJenka wants to merge 1 commit into
crewAIInc:mainfrom
MedviJenka:fix/skills-resolve-relative-to-project-root

Conversation

@MedviJenka

Copy link
Copy Markdown

Summary

Fixes #6585.

When loading a crew from JSONC (load_crew, load_crew_from_definition,
load_agent_from_definition), every relative path field (tools with the
custom: prefix, output_pydantic/response_format Python refs, etc.) is
resolved against project_root. The agent/crew skills field was the one
exception: it was passed through unresolved in
crewai/project/json_loader.py, and ultimately reached
crewai/skills/loader.py::discover_skills(Path(skill)), which resolves the
path against Path.cwd() at call time instead of project_root.

This meant the same crew definition would succeed or fail purely based on
the process's current working directory at import/call time — e.g. it
works when running a script directly from its own directory, but fails
with FileNotFoundError: Skill search path does not exist or is not a directory: skills when the same code runs as part of a server process
launched from a different cwd (uvicorn, docker, IDE run configs, etc.).

  • Adds _resolve_skill_path_strings() in crewai/project/json_loader.py,
    called for the skills field in both _resolve_agent_python_refs (agent
    definitions) and _resolve_crew_python_refs (crew-level skills).
  • Filesystem path strings (e.g. "./skills") are rewritten to absolute
    paths resolved against project_root, reusing the existing
    _resolve_project_path helper (same containment rules already applied to
    input_files).
  • Registry references (@org/name), inline SKILL.md string content, and
    values already resolved to non-string objects (e.g. via a {"python": ...} reference, or a pre-loaded Skill instance) are left unchanged.
  • Only affects JSON/JSONC loading; direct Python Agent(skills=...) /
    Crew(skills=...) usage is unaffected.

Test plan

  • Added TestResolveSkillPathStrings unit tests covering: relative
    path resolution against project_root (not cwd), registry refs
    passed through, inline SKILL.md content passed through, pre-loaded
    Skill objects passed through, and non-list values passed through.
  • Added test_skills_resolve_relative_to_project_root_not_cwd to
    TestLoadAgentFromDefinition, reproducing the issue's repro case
    end-to-end: agent loaded via load_agent_from_definition with
    skills: ["./skills"] from a cwd other than project_root correctly
    discovers the skill.
  • uv run pytest lib/crewai/tests/project/test_json_loader.py — 61
    passed.
  • uv run ruff check on changed files — clean.

🤖 Generated with Claude Code

Agent and crew `skills` filesystem path strings loaded from JSON/JSONC
definitions were passed through unresolved, so `discover_skills()`
resolved them against the process cwd at call time instead of
`project_root` like `tools` and `output_pydantic` already do. The same
crew definition would succeed or fail depending on the cwd the process
happened to start from (e.g. uvicorn/docker vs. running the script
directly).

Adds `_resolve_skill_path_strings()`, called for the `skills` field in
both `_resolve_agent_python_refs` and `_resolve_crew_python_refs`, which
rewrites plain filesystem path strings to absolute paths resolved
against `project_root`. Registry references (`@org/name`), inline
SKILL.md content, and already-resolved objects (e.g. from a Python
reference) are left untouched.

Fixes crewAIInc#6585.
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 723b6477-44fb-4719-9708-d2a8f6b4c23c

📥 Commits

Reviewing files that changed from the base of the PR and between 69c0308 and b6465dc.

📒 Files selected for processing (2)
  • lib/crewai/src/crewai/project/json_loader.py
  • lib/crewai/tests/project/test_json_loader.py

📝 Walkthrough

Walkthrough

The JSON loader now resolves ordinary agent and crew skills paths relative to project_root, while preserving registry references, inline definitions, and preloaded skill objects. Tests cover path resolution when the process working directory differs.

Changes

Skill Path Resolution

Layer / File(s) Summary
Skill normalization and special references
lib/crewai/src/crewai/project/json_loader.py, lib/crewai/tests/project/test_json_loader.py
Skill strings are resolved against project_root; registry references, inline YAML definitions, preloaded objects, and non-list inputs remain unchanged.
Agent and crew loader wiring
lib/crewai/src/crewai/project/json_loader.py, lib/crewai/tests/project/test_json_loader.py
Agent and crew Python-reference resolution applies skill normalization, with integration coverage for paths resolved independently of the current working directory.

Suggested reviewers: vinibrsl

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main fix: resolving agent and crew skills paths against project_root instead of cwd.
Description check ✅ Passed The description is clearly related to the change and accurately explains the skills path resolution fix and tests.
Linked Issues check ✅ Passed The changes address #6585 by resolving JSONC-loaded skills paths against project_root and preserving the documented exceptions.
Out of Scope Changes check ✅ Passed The PR stays focused on skills path resolution and matching tests, with no obvious unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent "skills" paths resolve against process cwd instead of project_root (unlike tools/output_pydantic)

1 participant