xai-org/grok-build · error
pin delete requires grove
Error message
pin delete requires grove
What it means
delete_pin_ref_gated is the non-grove (feature-gated) stub for removing a pin reference. In this build, pin deletion is only implemented through the grove daemon, so the function unconditionally bails: any caller attempting a pin delete without grove support compiled in / without the daemon gets this error.
Source
Thrown at crates/codegen/xai-fast-worktree/src/nfs/liveness.rs:529
let mut buf = Vec::new();
Read::take(file, MAX_MARKER_BYTES.saturating_add(1))
.read_to_end(&mut buf)
.ok()?;
if buf.len() as u64 > MAX_MARKER_BYTES {
return None;
}
Some(buf)
}
fn pin_exists(source: &Path, worktree_id: &str) -> Result<bool> {
{
let _ = (source, worktree_id);
Ok(false)
}
}
fn delete_pin_ref_gated(source: &Path, worktree_id: &str) -> Result<()> {
{
let _ = (source, worktree_id);
anyhow::bail!("pin delete requires grove")
}
}
#[cfg(feature = "metadata")]
pub fn identities_from_worktree_records(recs: &[crate::db::WorktreeRecord]) -> Vec<NfsIdentity> {
recs.iter()
.filter(|r| crate::worktree::is_grove_strategy(&r.creation_mode))
.map(|r| {
let grove = r
.metadata
.as_ref()
.and_then(|m| m.get("grove").or_else(|| m.get("nfs")));
let backing = grove
.and_then(|n| n.get("backing"))
.and_then(|b| b.as_str())
.filter(|s| !s.is_empty())
.map(PathBuf::from);
let pin = grove
.and_then(|n| n.get("source_pin"))View on GitHub (pinned to bc7f02eddd)
Solutions
- Ensure pin deletion goes through the grove daemon path (gate gc_orphan_pins on grove strategy, e.g. filter records with is_grove_strategy)
- Compile/enable the grove feature so the real implementation is used instead of the stub
- Skip pin deletion for non-grove worktrees instead of calling the gated function
Example fix
// before
for id in orphans {
delete_pin_ref_gated(&source, id)?;
}
// after
for rec in recs.iter().filter(|r| crate::worktree::is_grove_strategy(&r.creation_mode)) {
delete_pin_ref_gated(&rec.source, &rec.worktree_id)?;
} Defensive patterns
Strategy: fallback
Validate before calling
#[cfg(feature = "metadata")]
let is_grove = recs.iter().any(|r| crate::worktree::is_grove_strategy(&r.creation_mode));
if !is_grove { return Ok(()); } // skip pin deletion Try / catch
match delete_pin_ref_gated(&source, id) {
Err(e) if e.to_string() == "pin delete requires grove" => {
// skip or route through the grove daemon path
}
r => r?,
} Prevention
- Only call pin deletion for records with grove creation_mode
- Build with the grove/metadata features enabled when pin management is needed
- Wrap gated calls with cfg(feature) or a capability check
When it happens
Trigger: Calling gc_orphan_pins (which invokes delete_pin_ref_gated) on a code path that is not gated to grove-managed worktrees — i.e. trying to delete an NFS pin reference outside the grove-managed flow.
Common situations: Running an orphan-pin GC while worktrees were created with a non-grove creation_mode; a build without the metadata/grove gating reaching the stub; callers porting old pin-cleanup code to the new gated API.
Related errors
- unmounted dest {} has grove metadata without a worktree id;
- invalid worktree id from dest: {worktree_id}
- invalid worktree id {:?}
- mount table inconclusive for {}; refusing remove
- daemon RemoveWorktree failed: {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/552e5ecad2098c96.
Report an issue: GitHub.