zed-industries/zed · error

Path {} is not in the project

Error message

Path {} is not in the project

What it means

resolve_project_path is the authorization gate every agent tool path passes through. It first maps the path with Project::find_project_path; None means the path is not under any open worktree, and this error (worded for the model) is returned so the tool refuses to touch paths outside the project.

Source

Thrown at crates/agent/src/tools/tool_permissions.rs:400

/// # Returns
///
/// - `Ok(ResolvedProjectPath::Safe(project_path))` — the path resolves to a
///   location within the project boundaries.
/// - `Ok(ResolvedProjectPath::SymlinkEscape { .. })` — the path resolves
///   through a symlink to a location outside the project. Agent tools should
///   prompt the user before proceeding.
/// - `Err(..)` — the path could not be found in the project or could not be
///   verified. The error message is suitable for returning to the model.
pub fn resolve_project_path(
    project: &Project,
    path: impl AsRef<Path>,
    canonical_worktree_roots: &[PathBuf],
    cx: &App,
) -> Result<ResolvedProjectPath> {
    let path = path.as_ref();
    let project_path = project
        .find_project_path(path, cx)
        .ok_or_else(|| anyhow!("Path {} is not in the project", path.display()))?;

    let worktree = project
        .worktree_for_id(project_path.worktree_id, cx)
        .ok_or_else(|| anyhow!("Could not resolve path {}", path.display()))?;
    let snapshot = worktree.read(cx);

    // Fast path: if the entry exists in the snapshot and is not marked
    // external, we know it's safe (the background scanner already verified).
    if let Some(entry) = snapshot.entry_for_path(&project_path.path) {
        if !entry.is_external {
            return Ok(ResolvedProjectPath::Safe(project_path));
        }

        // Entry is external (set by the worktree scanner when a symlink's
        // canonical target is outside the worktree root). Return the
        // canonical path if the entry has one, otherwise fall through to
        // filesystem-level canonicalization.
        if let Some(canonical) = &entry.canonical_path {

View on GitHub (pinned to bc538def45)

Solutions

  1. Open the containing folder as an additional worktree (Add Folder to Project) and retry
  2. Restrict the request to paths inside the current project
  3. Fix stale absolute prefixes or wrong-relative paths in the request

Example fix

// before — path outside every worktree
edit_file(path="/etc/app/config.toml", ...)

// after — the folder is added to the project first
edit_file(path="/home/me/work/app/config.toml", ...)
Defensive patterns

Strategy: validation

Validate before calling

if project.find_project_path(&path, cx).is_none() {
    // path is outside every worktree; reject before invoking the tool
}

Try / catch

Match 'is not in the project' in the tool error, then either add the containing folder as a worktree or re-scope the request to in-project paths.

Prevention

When it happens

Trigger: Any agent tool call whose path resolves outside every worktree: absolute paths under ~ or /etc, relative paths that escape the roots, or paths copied from a different project or machine.

Common situations: The agent proposes editing a config outside the workspace; the project root was moved or re-opened elsewhere; a stale absolute prefix survives in a saved prompt.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/a793036f4a008403. Report an issue: GitHub.