windmill-labs/windmill · error

Internal Error: {path} is not under {repository_dir}

Error message

Internal Error: {path} is not under {repository_dir}

What it means

The Java executor's Maven dependency cache (`move_to_repository`) receives a `RequiredDependency.path` that is expected to live inside `repository_dir` (the local Maven repository). `strip_prefix` fails when the path isn't actually a subpath of the repository dir, meaning an internal invariant is violated — this is always a bug in how the dependency path was computed or cached, not a user-input error.

Source

Thrown at backend/windmill-worker/src/java_executor.rs:566

                w.found = true;
                return Ok(());
            }
        }
        for (name, entry) in subdirs {
            below.push(name);
            find_and_copy(&entry.path(), below, wanted).await?;
            below.pop();
        }
        Ok(())
    }

    let mut wanted = deps
        .iter()
        .map(|RequiredDependency { path, display_name, .. }| {
            let suffix = path
                .strip_prefix(repository_dir)
                .filter(|suffix| suffix.starts_with('/'))
                .ok_or_else(|| anyhow!("Internal Error: {path} is not under {repository_dir}"))?;
            Ok(Wanted {
                coordinate: suffix
                    .split('/')
                    .filter(|component| !component.is_empty())
                    .map(str::to_owned)
                    .collect(),
                destination: path.clone(),
                display_name: display_name.clone(),
                found: false,
            })
        })
        .collect::<anyhow::Result<Vec<_>>>()?;
    // longest coordinate first: a group id ending in another one's coordinates (com.org.foo:bar
    // over org.foo:bar) would otherwise be free to claim the shorter one's directory
    wanted.sort_by_key(|w| std::cmp::Reverse(w.coordinate.len()));

    find_and_copy(&PathBuf::from(fetch_dir), &mut vec![], &mut wanted).await?;

View on GitHub (pinned to e474e8803c)

Solutions

  1. Clear the Maven dependency cache/repository directory so paths are regenerated under the current `repository_dir`.
  2. Ensure the repository dir mount point is identical between the run that cached artifacts and this run (same Docker volume path, same `MAVEN_REPO` setting).
  3. If this fires on registry-supplied coordinates, audit the registry URL — the path likely contains `..` or an absolute component escaping the repo; fix the registry configuration.
  4. If reproducible on a fresh cache, file a bug — the path construction in the java executor is violating its own invariant.

Example fix

// before: cache written with old repo dir
// /old/repo/org/example/foo/1.0/foo-1.0.jar vs repo=/new/repo
// after: wipe and repopulate the cache under the current repo
rm -rf /new/repo && wmill worker start # re-downloads dependencies
Defensive patterns

Strategy: validation

Validate before calling

// before installing, sanity-check every dep path sits under the repo
for dep in deps {
    if !dep.path.starts_with(repository_dir) {
        return Err(format!("{} is outside repository {}", dep.path, repository_dir));
    }
}

Type guard

fn under_repo(path: &Path, repo: &Path) -> bool {
    path.strip_prefix(repo).map(|s| s.starts_with("/")).unwrap_or(false)
}

Prevention

When it happens

Trigger: A cached dependency's stored path was written with a different repository_dir (changed `MAVEN_REPO` config, moved cache, different worker/container mount), or path construction produced an absolute path outside the repo (e.g. registry URL trickery — see tests like `artifacts_are_found_whatever_the_registry_url_path_is`).

Common situations: Worker cache persisted across a Windmill version where the repository layout changed; Docker volume mounted at a different path than when artifacts were downloaded; a malicious/misconfigured Maven registry returning a coordinate whose resolved path escapes the repository (path-traversal guard firing).

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/4915d09a6f154edd. Report an issue: GitHub.