abhigyanpatwari/GitNexus · error · ValueError

phase did not create or change its required artifact: {relat

Error message

phase did not create or change its required artifact: {relative}

What it means

Raised by enforce_phase_workspace (runner_artifacts.py:207) when the allowed artifact's state in the 'after' snapshot is identical to its state in the 'before' snapshot. The phase contract says a planning/work phase must create or modify its one declared artifact; an unchanged artifact means the phase produced no evidence and the result is unverifiable.

Source

Thrown at eval/workflow_bench/runner_artifacts.py:207

    worktree: Path,
    before: dict[str, str],
    *,
    allowed_artifact: Path,
) -> None:
    """Require a phase to change only its one explicit workspace artifact."""

    root = worktree.expanduser().absolute()
    artifact = allowed_artifact.expanduser().absolute()
    try:
        relative = PurePosixPath(artifact.relative_to(root).as_posix())
    except ValueError as exc:
        raise ValueError(f"phase artifact escapes the workspace: {allowed_artifact}") from exc
    after = workspace_snapshot(root)
    changed = {path for path in before.keys() | after.keys() if before.get(path) != after.get(path)}
    artifact_key = relative.as_posix()
    artifact_state = after.get(artifact_key)
    if before.get(artifact_key) == artifact_state:
        raise ValueError(f"phase did not create or change its required artifact: {relative}")
    if artifact_state is None or not artifact_state.startswith("f:"):
        raise ValueError(f"phase artifact must be a regular non-symlink file: {relative}")

    try:
        metadata = artifact.lstat()
        descriptor = os.open(artifact, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0))
    except OSError as exc:
        raise ValueError(f"phase artifact must be a readable regular non-symlink file: {relative}") from exc
    try:
        opened = os.fstat(descriptor)
        if (
            stat.S_ISLNK(metadata.st_mode)
            or not stat.S_ISREG(metadata.st_mode)
            or not stat.S_ISREG(opened.st_mode)
            or metadata.st_dev != opened.st_dev
            or metadata.st_ino != opened.st_ino
        ):
            raise ValueError(f"phase artifact must be a regular non-symlink file: {relative}")

View on GitHub (pinned to d540b00184)

Solutions

  1. Check the run transcript to see what path the model actually wrote to; align allowed_artifact with that path or fix the prompt.
  2. Confirm the artifact_key (relative posix path) matches what the model writes — mismatches in casing or trailing slashes cause this.
  3. If the model genuinely produced nothing, treat it as a failed run (record resolved=False) rather than retry with the same prompt.

Example fix

# before: artifact path does not match what the model writes
enforce_phase_workspace(wt, before, allowed_artifact=wt/'docs/plans/plan-v1.md')
# model writes docs/plans/plan-v2.md

# after
enforce_phase_workspace(wt, before, allowed_artifact=wt/'docs/plans/plan-v2.md')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import os

artifact = Path(allowed_artifact).expanduser().absolute()
assert artifact.exists(), f"artifact not created: {artifact}"
assert artifact.is_file() and not artifact.is_symlink(), (
    f"artifact is not a regular file: {artifact}")
# The phase must have changed it relative to `before` — caller checks the
# snapshot entry, but a quick existence/type check catches the common case.

Prevention

When it happens

Trigger: before.get(artifact_key) == artifact_state after the phase ran. The model did not write to the declared artifact path, wrote to a different path, or wrote then reverted it; the artifact path was wrong (typo / wrong directory).

Common situations: The planning prompt told the model to write docs/plans/foo.md but it wrote docs/plans/bar.md; the work phase's artifact is mis-specified relative to what the model actually edits; the model failed silently and produced nothing; the model edited the file but then ran git checkout to revert.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/b893d40a14a59334. Report an issue: GitHub.