xai-org/grok-build · error
invalid worktree id from dest: {worktree_id}
Error message
invalid worktree id from dest: {worktree_id} What it means
In `create`, after deriving a worktree id from the destination path (via the metadata feature or `worktree_id_from_path`), the id is validated with `nfs::is_safe_worktree_id`. If it fails (contains path separators, traversal sequences, or other unsafe characters/segments), creation aborts with this message. It protects against unsafe ids being stored/symlinked on NFS-backed storage.
Source
Thrown at crates/codegen/xai-fast-worktree/src/api.rs:423
///
/// This is a **blocking** operation. Callers should use `spawn_blocking`
/// when calling from async contexts.
pub fn create(self) -> Result<WorktreeReport> {
// One canonical dest for the plan id, IPC idempotency key, and DB id.
let dest = crate::worktree::plan::canonicalize_for_id(&self.dest);
let worktree_id = {
#[cfg(feature = "metadata")]
{
self.worktree_id
.unwrap_or_else(|| crate::worktree::plan::worktree_id_from_path(&dest))
}
#[cfg(not(feature = "metadata"))]
{
crate::worktree::plan::worktree_id_from_path(&dest)
}
};
if !crate::nfs::is_safe_worktree_id(&worktree_id) {
anyhow::bail!("invalid worktree id from dest: {worktree_id}");
}
#[cfg(feature = "metadata")]
let meta_fields = (
self.worktree_kind,
self.session_id,
worktree_id.clone(),
self.source.clone(),
self.git_ref.clone(),
self.metadata,
);
let plan = crate::worktree::WorktreePlan {
source: self.source,
dest,
git_ref: self.git_ref,
parallelism: self.parallelism,
channel_buffer: self.channel_buffer,View on GitHub (pinned to bc7f02eddd)
Solutions
- Inspect the error text: it interpolates the offending `worktree_id`; check it for `/`, `..`, empty segments, or illegal characters.
- Pass a flat, simple destination path directly under the managed worktrees root so the derived id is a single safe component.
- Pre-validate with `crate::nfs::is_safe_worktree_id(&worktree_id_from_path(dest))` before calling create.
- Remove `..`, symlinks, or redundant separators from the dest path (e.g. use `std::fs::canonicalize` on the parent first).
- If the id comes from an external caller, sanitize or reject it before constructing dest.
Example fix
// before
let opts = CreateOptions::new().dest("/srv/worktrees/../evil/session1");
api.create(opts)?; // invalid worktree id from dest: ../evil/session1
// after
let dest = Path::new("/srv/worktrees").join("session1"); // single safe component
assert!(crate::nfs::is_safe_worktree_id(&crate::worktree::plan::worktree_id_from_path(&dest)));
api.create(CreateOptions::new().dest(dest))?;
Defensive patterns
Strategy: validation
Validate before calling
use std::path::Path;
fn dest_id_is_safe(dest: &Path) -> bool {
match dest.file_name().and_then(|s| s.to_str()) {
Some(name) => !name.is_empty()
&& !name.contains('/')
&& name != "." && name != ".."
&& crate::nfs::is_safe_worktree_id(name),
None => false,
}
}
assert!(dest_id_is_safe(&dest), "dest yields unsafe worktree id"); Type guard
fn is_safe_worktree_id(id: &str) -> bool {
!id.is_empty()
&& !id.contains('/')
&& !id.contains("..")
&& id.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
} Try / catch
match api.create(opts) {
Err(e) if e.to_string().starts_with("invalid worktree id from dest") => {
eprintln!("fix dest path: {e}");
}
r => r?,
} Prevention
- Always build dest under the managed root with a single filename component
- Canonicalize parent directories to eliminate '..' and symlink surprises
- Pre-check ids with is_safe_worktree_id before calling create
- Never accept raw user input as a worktree id without sanitization
When it happens
Trigger: Calling a `create`-style API whose `dest` path yields an unsafe worktree id: a dest outside the managed root, a dest whose filename contains slashes or `..`/`.` traversal, or a custom/oddly nested dest that makes `worktree_id_from_path` return a multi-segment or empty id.
Common situations: Passing a destination path with `..` components or a trailing nested structure; pointing dest at a directory whose basename is not a valid id (empty, contains `/`); mixing feature flags (`metadata`) so the id is derived differently than expected; NFS-mounted storage where safe ids are mandatory.
Related errors
- invalid worktree id {:?}
- preserve on a projected Grove source is not supported
- e.error (daemon error message propagated via anyhow!)
- OUT_OF_DISK_CONTEXT
- overlay mount delegation not supported by this delegate
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/6d6108d605431e20.
Report an issue: GitHub.