Skip to content

[Phase 2.5] Per-edit lint gate returns FAILED when linter binary is missing #372

Description

@frankbria

Problem

gates.run_lint_on_file() returns GateStatus.FAILED when the linter binary (e.g., ruff) is not installed in the target project's venv. This causes the ReactAgent to waste all 30 iterations trying to "fix" phantom lint errors that don't actually exist.

Root Cause

In codeframe/core/gates.py, the run_lint_on_file() function:

  1. Checks if the binary is available via shutil.which(cfg.check_available) (line 651)
  2. If not found but cfg.use_uv is True and uv is on PATH, it proceeds (line 652-653)
  3. Runs ["uv", "run", "ruff", "check", ...] in the target project directory
  4. If uv run ruff fails because ruff isn't a dependency (e.g., it's under optional dev deps only), returncode != 0GateStatus.FAILED

The gate cannot distinguish between "ruff not found" (exit code 2, stderr: "Failed to spawn: ruff") and "ruff found lint errors" (exit code 1, stdout: error details). Both result in GateStatus.FAILED.

Impact

  • Every file creation by the ReactAgent gets marked FAILED
  • Agent wastes all 30 iterations trying to fix errors that don't exist
  • Effectively makes the agent unable to complete any task on projects without dev dependencies installed

Observed Behavior

[ReactAgent] Tool: create_file
AGENT_STEP_COMPLETED path=src/task_tracker/models.py
AGENT_STEP_COMPLETED path=src/task_tracker/models.py status=FAILED  ← ruff not found

After installing ruff: same file creation now produces real lint errors the agent CAN fix.

Proposed Fix

In gates.run_lint_on_file(), after running the subprocess:

  1. Check stderr for "Failed to spawn" or similar tool-not-found patterns
  2. If the tool was not found, return GateStatus.SKIPPED instead of GateStatus.FAILED
  3. Alternatively, parse exit code 2 specifically (ruff uses 2 for "command not found" vs 1 for "lint errors found")

Files

  • codeframe/core/gates.pyrun_lint_on_file() function (line 631+)
  • codeframe/core/react_agent.py_execute_tool_with_lint() and _run_lint_on_file() (lines 564+)

Test

After fix: running a task on a project without ruff installed should show status=SKIPPED for lint checks, not status=FAILED.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingphase-2Phase 2: Server Layer as Thin Adapter

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions