Skip to main content

Fix Linter Errors Dynamically

This example demonstrates a more advanced Bosun workflow that dynamically identifies linter errors in your codebase and then spawns individual AI agents to fix each error. This showcases the power of combining run steps for command execution with for_each loops and agent steps for targeted, automated code remediation.

Workflow Definition (bosun.yaml)

name: fix-linter-errors-dynamically
description: Identifies linter errors and uses agents to fix them, then creates a PR.

inputs:
maxErrors:
type: Number
required: false
description: Limit how many erroring files to process.

steps:
- id: lint_errors
name: Run linter and get errors
run: |
# Simulate a linter command that outputs file paths with errors.
# In a real scenario, this would be your actual linter command (e.g., `eslint --format compact src/`).
# For this example, we'll just list some files that *would* have errors.
echo "src/components/BadComponent.tsx"
echo "src/utils/BrokenHelper.ts"
echo "src/pages/UnformattedPage.tsx"
# The output of this step will be a list of file paths, one per line.

- id: fix_lint_errors
name: Fix each linter error with an agent
for_each:
from: '{{ outputs.lint_errors | split(pat="\n") | filter(value) | slice(end=inputs.maxErrors) | json_encode() }}'
agent:
extends: Coding
instructions: "Apply automatic linting fixes to the file {{ for_each.value }}. Focus on common formatting issues and simple syntax corrections."
role: "You are a meticulous code formatter and linter expert."
constraints:
- "Use the project's standard linting rules (assume ESLint/Prettier are configured)."
- "Only apply fixes that do not change code logic."
- "Ensure the file remains syntactically correct and passes type checks."
- "Focus solely on the specified file: {{ for_each.value }}"
- "Do not make any unrelated changes."

- id: open_pr
name: Create a pull request for fixes
agent:
extends: Default
role: "You create pull requests for automated code fixes."
instructions: "Create a draft pull request for all lint fixes applied in this run."
toolboxes: [repository_read, dangerous]
tools:
- name: create_pull_request
extends: create_or_update_pull_request
with:
draft: true

starts_with: lint_errors
ends_with: open_pr

edges:
- from: lint_errors
to: fix_lint_errors
- from: fix_lint_errors
to: open_pr

How it Works

  1. Run Linter: The lint_errors run step simulates executing a linter command. In a real-world scenario, you would replace echo "..." with your actual linter command (for example eslint --format compact src/). The output is expected to be a list of file paths, one per line.
  2. Iterate and Fix: The graph moves from lint_errors to fix_lint_errors. This for_each step takes outputs.lint_errors, splits it into file paths, filters out empty strings, and iterates over each file. The optional numeric input inputs.maxErrors limits the workload.
    • For each file path, a new Coding agent is spawned.
    • The agent's instructions dynamically include {{ for_each.value }}, telling it exactly which file to focus on.
    • The agent's role and constraints guide it to apply automatic linting fixes without altering code logic.
  3. Create Pull Request: After the fan-out step completes, the graph continues to open_pr, where a Default agent creates a draft pull request containing the accumulated fixes.
Replace the placeholder command

Swap the echo statements with your actual linter invocation—Bosun only needs a newline-delimited list of files to drive the loop.