How the Auto-Fix System Categorizes and Applies Fixes in no-mistakes

The auto-fix system filters pipeline findings for auto-fixable flags, validates per-step limits against database state, and dispatches AI agents to generate and commit patches automatically when safe.

The no-mistakes CLI includes a built-in auto-fix system that automatically resolves failures discovered during pipeline runs, such as lint errors, CI failures, and merge conflicts. The system operates through a structured decision pipeline that categorizes findings and respects configurable safety limits. According to the source code in kunchenguid/no-mistakes, the implementation spans multiple layers from JSON filtering to agent invocation.

How the Auto-Fix System Processes Failures

The auto-fix system operates through four distinct phases that transform raw pipeline failures into committed fixes.

Step 1: Finding Generation and JSON Filtering

Each pipeline step emits findings as JSON objects describing detected issues. The system distinguishes auto-fixable problems from those requiring human review by inspecting the auto_fixable boolean flag.

In internal/pipeline/findings.go, the helper function autoFixableFindingsJSON filters the raw findings to extract only those marked with "auto_fixable": true. This filtered subset determines whether the auto-fix loop activates.

Step 2: Executor Decision Logic

The executor evaluates whether to trigger an auto-fix attempt based on the step outcome and remaining quota. In internal/pipeline/executor.go approximately lines 680-690, the code checks three conditions: outcome.AutoFixable must be true, the global auto-fix setting must be enabled, and the autoFixAttempts counter must remain below the configured autoFixLimit.

When these conditions pass, the executor increments the attempt counter and logs the operation via slog.Info, capturing the step name, current attempt number, and maximum limit.

// executor.go (excerpt)
if outcome.AutoFixable && autoFixLimit > 0 && autoFixAttempts < autoFixLimit {
    fixableFindings := autoFixableFindingsJSON(outcome.Findings)
    autoFixAttempts++
    slog.Info("auto-fixing step", "step", stepName,
        "attempt", autoFixAttempts, "max", autoFixLimit)
    // Launch agent...
}

Step 3: Agent Invocation and Patch Application

For eligible steps, the system launches an AI agent (such as Codex or Claude) with a prompt encoding the filtered findings. The concrete implementation resides in internal/pipeline/steps/ci_fix.go within the autoFixCI function.

If the agent produces a patch that applies cleanly, the system commits the changes and re-executes the step. The database persists the current auto_fix_limit and attempt count via gate.autoFixes, ensuring subsequent runs respect the configured ceiling. When patches fail to apply or the limit exhausts, the pipeline falls back to manual approval.

Categorization of Findings

The auto-fix system categorizes all pipeline findings into three distinct types to determine resolution paths.

Auto-Fixable Findings

Auto-fixable findings are issues the system can resolve without human intervention, such as simple lint violations or single-line test fixes. These must carry the "auto_fixable": true flag in their JSON representation. Only findings passing through autoFixableFindingsJSON enter the auto-fix loop.

Ask-User Findings

Ask-user findings lack the auto-fixable flag or explicitly set it to false, covering complex refactorings or security issues. These trigger the NeedsApproval status, pausing the pipeline until human review occurs.

Outcome Flags

After execution, the executor creates an Outcome struct containing:

  • AutoFixable: A boolean indicating whether any auto-fixable findings exist
  • Findings: The complete JSON list for potential filtering

The executor considers the auto-fix path exclusively when Outcome.AutoFixable evaluates to true.

Configuration and Limits

Users control auto-fix behavior through global defaults and per-step overrides. In internal/config/config.go, the autoFixDefaults() function establishes:

  • autoFix.enabled: Master switch defaulting to true
  • autoFix.limit: Per-step maximum attempts defaulting to 1
  • autoFix.rounds: Tracking for summary output

The AutoFixLimit(stepName) function reads effective limits, while StartStepWithAutoFixLimit initializes the database state for each execution.

Repository-specific .no-mistakes.yaml files override these defaults:

steps:
  lint:
    auto_fix:
      enabled: true
      limit: 2
  test:
    auto_fix:
      enabled: false

This configuration disables auto-fix for the test step while allowing two attempts for lint fixes.

Summary

Frequently Asked Questions

How does the auto-fix system determine which findings to fix automatically?

The system inspects the auto_fixable boolean field within each finding's JSON object. The autoFixableFindingsJSON helper in internal/pipeline/findings.go extracts only findings where this flag is true, filtering out security issues or complex changes that require human judgment.

What happens when the auto-fix limit is reached?

When autoFixAttempts meets or exceeds autoFixLimit (tracked in the database via gate.autoFixes), the executor stops the auto-fix loop and marks the step as NeedsApproval. The pipeline pauses for manual intervention rather than attempting further automatic repairs.

Can I disable auto-fix for specific pipeline steps?

Yes. Create a .no-mistakes.yaml file in your repository and set auto_fix.enabled to false for the specific step. For example, disabling auto-fix for tests while keeping it for linting requires configuring the test step with auto_fix.enabled: false as shown in the configuration examples.

Where does the auto-fix system store attempt counts and limits?

The system persists auto-fix state in the database using the gate.autoFixes field. The executor calls StartStepWithAutoFixLimit to initialize limits at step start, and increments counters during execution to enforce per-step ceilings across multiple runs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →