abhigyanpatwari/GitNexus · error · ValueError
planning deleted existing plan artifact(s): {deleted}
Error message
planning deleted existing plan artifact(s): {deleted} What it means
Thrown by new_plan_doc when comparing the before-snapshot to the after-snapshot of plan artifacts. If any path present in the before-dict is absent from the after-dict, the planning phase deleted a previously existing plan markdown/html file. The benchmark requires planning to be additive, so destructive behavior is rejected as ambiguous evidence.
Source
Thrown at eval/workflow_bench/runner_artifacts.py:293
if not stat.S_ISREG(opened.st_mode) or opened.st_dev != metadata.st_dev or opened.st_ino != metadata.st_ino:
raise ValueError(f"plan artifact changed while opening: {path}")
with os.fdopen(descriptor, "rb", closefd=False) as handle:
snapshot[path] = hashlib.file_digest(handle, "sha256").hexdigest()
after = os.fstat(descriptor)
if (opened.st_size, opened.st_mtime_ns) != (after.st_size, after.st_mtime_ns):
raise ValueError(f"plan artifact changed while hashing: {path}")
finally:
os.close(descriptor)
return snapshot
def new_plan_doc(worktree: Path, before: dict[Path, str]) -> Path:
"""Return the sole new or modified plan, rejecting ambiguous evidence."""
after = snapshot_plan_docs(worktree)
deleted = sorted(path for path in before if path not in after)
if deleted:
raise ValueError("planning deleted existing plan artifact(s): " + ", ".join(str(path) for path in deleted))
changed = sorted(path for path, digest in after.items() if before.get(path) != digest)
if len(changed) != 1:
raise ValueError(f"planning must create or modify exactly one plan artifact; observed {len(changed)}")
return changed[0]
def make_worktree(repo: Path, ref: str, parent: Path) -> Path:
"""Create a self-contained clone per benchmark arm."""
target = Path(tempfile.mkdtemp(prefix="wfbench-", dir=parent))
target.rmdir()
try:
run_checked(
[
"git",
"clone",
"--no-local",
"--no-hardlinks",View on GitHub (pinned to d540b00184)
Solutions
- Make the planning step only create or modify plans, never delete existing ones.
- If a stale plan must be replaced, overwrite it in place rather than unlink + create.
- Audit agent prompts/tooling for any `rm`/`git clean` touching docs/plans.
- Pre-populate the worktree with no pre-existing plans if the task does not require editing one, so there is nothing to delete.
Example fix
// before — agent deletes then writes os.remove(plan_path) plan_path.write_text(new_plan) // after — overwrite in place, never delete plan_path.write_text(new_plan)
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def plans_only_added(before: dict[Path, str], after: dict[Path, str]) -> bool:
return all(p in after for p in before) Type guard
null
Try / catch
try:
new_plan_doc(worktree, before)
except ValueError as e:
if 'deleted existing plan artifact' in str(e):
# planning was destructive; fix the agent/prompt to overwrite, not delete
raise
raise Prevention
- Instruct planning steps to create or overwrite plans, never unlink existing ones.
- Pre-populate the worktree with no plans if none need editing.
- Audit agent tool output for `rm`/`git clean` against docs/plans.
- Add a unit test asserting plans_only_added(before, after) before calling new_plan_doc.
When it happens
Trigger: In new_plan_doc, `deleted = sorted(path for path in before if path not in after)` is non-empty — a plan file that existed before the planning phase no longer exists after it.
Common situations: An agent removes a stale plan before writing its own; a git checkout/clean inside the agent step deletes docs/plans; a setup hook that tidies the plans dir; the agent treats docs/plans as scratch space.
Related errors
- plan artifact changed while opening: {path}
- plan artifact changed while hashing: {path}
- planning must create or modify exactly one plan artifact; ob
- {label} is unavailable: {path}: {exc}
- {label} must be a real non-symlink directory: {path}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/fda3c296f4230abd.
Report an issue: GitHub.