P001 inline-tool
A run: step calls a build, test, lint or deploy tool directly instead of going through
the task runner.
Severity: error; tolerated when a baseline allows it; allowed when an allow comment or config entry covers it.
Example
Section titled “Example”# Taskfile.yml has a test task that runs `pnpm test`.jobs: web: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - name: Test run: pnpm test - name: Lint run: npx eslint ..github/workflows/ci.yml 7:14 P001 inline-tool step "Test" in job "web" runs 'pnpm test' directly; already available as 'task test' 9:14 P001 inline-tool step "Lint" in job "web" runs 'npx eslint .' directlyWhen a task runs the same command and nothing else, the message ends with “already
available as” and the task to call. A task that also runs other commands, has
dependencies or calls other tasks is never suggested, as calling it would run more than
the step. Package runners such as npx, pnpm exec and uv run are looked through
on both sides, so npx eslint . would match a task that runs eslint .. The task must
also run in the step’s working-directory: a step in web/ matches a task with
dir: web, not one that runs at the root.
Why it matters
Section titled “Why it matters”The task is the definition of how to test or lint. A step that calls the tool directly
keeps working after the task changes, so CI quietly runs something different from what
task test runs locally.
How to fix it
Section titled “How to fix it”- Call the task:
run: task test.ci-parity fixmakes this change for you when it’s safe; see Fixing findings. - When no task exists yet, add one to the runner file and call it.
When it’s deliberate
Section titled “When it’s deliberate”Allow the step with a reason, on its line or the line above:
- run: docker push ghcr.io/acme/widget-service:dev # ci-parity: allow images publish only from CIOr allow a pattern in .ci-parity.yml, or stop flagging the tool with tools.remove;
see Configuring.
See also
Section titled “See also”Last reviewed: 2026-10-29