Rules
Rules
Every finding flowpact reports, grouped by category. Each code links to why it matters and how to fix it.
Codes have the form <PREFIX><category><nn> — built-in rules use FP, so FP4xx are matrix rules.
Severity is configurable per rule; codes never change meaning. Plugin rules use their own prefix (for example ACME101).
Inputs (FP1xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP101 | missing-required-input | 🔴 error | A reusable workflow or local action is called without one of its required inputs. |
FP102 | unknown-input | 🔴 error | A caller passes an input the reusable workflow or local action does not declare. |
FP103 | input-type-mismatch | 🔴 error | A literal value passed to a typed workflow_call input has the wrong type. |
FP104 | unused-input | 🟡 warning | An input is declared but never read anywhere in the workflow or action. |
FP105 | optional-input-no-default-in-condition | 🟡 warning | An optional input without a default decides an if: condition. |
FP106 | passthrough-dropped | 🔵 info | A caller passes a value to an input that the callee declares but never reads. |
FP107 | optional-forwarded-to-required | 🟡 warning | A required input of a callee is fed from an optional input that has no default. |
FP108 | undefined-input-ref | 🔴 error | An expression reads inputs.\<name\> that the workflow or action does not declare. |
Secrets (FP2xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP201 | missing-required-secret | 🔴 error | A reusable workflow is called without one of its required secrets. |
FP202 | unknown-secret | 🔴 error | A caller passes a secret the reusable workflow does not declare. |
FP203 | unused-secret | 🟡 warning | A workflow_call secret is declared but never read. |
FP204 | secrets-inherit | 🔵 info | secrets: inherit hands every repository secret to the callee; flowpact lists what is actually needed. |
FP205 | undeclared-secret-ref | 🔴 error | A reusable workflow reads a secret it does not declare, and some caller does not use secrets: inherit. |
Outputs (FP3xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP301 | undefined-output-ref | 🔴 error | An expression reads an output (needs.*, jobs.*, steps.*) that is never defined. |
FP302 | output-ref-without-needs | 🔴 error | needs.\<job\> is read in a job that does not list \<job\> under needs:. |
FP303 | unused-output | 🟡 warning | A job, workflow or action output is declared but no consumer reads it. |
FP304 | step-output-never-written | 🟡 warning | An output is read from a run: step whose script writes other outputs, but never this one. |
Matrix (FP4xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP401 | empty-binding-for-matrix-combo | 🔴 error | An input passed under with: is empty for some matrix combinations because a matrix key is missing there. |
FP402 | matrix-key-missing-in-combo | 🟡 warning | An expression reads a matrix key that is only defined in some combinations. |
FP403 | dynamic-matrix-unverified | 🔵 info | The matrix is computed at runtime, so flowpact cannot check that every combination defines the keys it reads. |
FP404 | undefined-matrix-key | 🔴 error | An expression reads a matrix key that no combination defines (or the job has no matrix). |
FP405 | unused-matrix-shape | 🟡 warning | A matrixShapes entry in the config does not match a job with a runtime-computed matrix. |
FP406 | matrix-too-large | 🔴 error | A job's matrix produces more than 256 jobs, which GitHub rejects. |
Env & expressions (FP5xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP501 | undefined-env-ref | 🟡 warning | $\{\{ env.NAME \}\} reads a variable that is not defined at workflow, job or step level, nor written to $GITHUB_ENV earlier. |
FP502 | expression-parse-error | 🔴 error | A $\{\{ \}\} expression (or an if: condition) cannot be parsed. |
FP503 | schema-violation | 🔴 error | The file does not match GitHub’s workflow / action schema (validated with GitHub’s own parser). |
FP504 | yaml-syntax-error | 🔴 error | The file is not valid YAML. |
FP505 | context-not-available | 🔴 error | An expression uses a context or function that GitHub does not allow in that field (e.g. env in a reusable workflow call’s with:). |
Graph structure (FP6xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP601 | call-cycle | 🔴 error | Reusable workflows call each other in a cycle. |
FP602 | nesting-depth | 🔴 error | A chain of reusable workflow calls is deeper than the configured limit (limits.nestingDepth). |
FP603 | remote-unverified | 🔵 info | A job calls a reusable workflow in another repository; its interface is not verified. |
FP604 | needs-without-data | ⚪ off (opt-in) | A job lists another job under needs: but never reads its outputs or result (opt-in). |
FP605 | large-interface | 🔵 info | A reusable workflow declares more inputs than limits.maxInputs. |
FP606 | missing-local-target | 🔴 error | A local uses: ./... points to a workflow or action that does not exist. |
FP607 | unreferenced-reusable-workflow | 🔵 info | A workflow can only be triggered by workflow_call, but nothing in this repository calls it. |
FP608 | undefined-needs-job | 🔴 error | A job lists a job under needs: that does not exist. |
FP609 | callee-not-reusable | 🔴 error | A job calls a local workflow that has no on.workflow_call trigger. |
Contracts (FP8xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP801 | contract-missing | 🔴 error | A workflow or local action has no contract in .github/flowpact/ (check mode). |
FP802 | contract-outdated | 🔴 error | The locked contract no longer matches the workflow — non-breaking changes to its interface or wiring. |
FP803 | breaking-interface-change | 🔴 error | A change breaks the locked contract: an input became required, an input/secret/output was removed, or a type changed. |
FP804 | orphan-contract | 🔴 error | A contract file exists for a workflow or action that no longer exists. |
FP805 | contract-invalid | 🔴 error | A contract file cannot be read (invalid YAML or schema), usually because it was edited by hand or merged badly. |
FP810 | impact-under-declared | 🔴 error | The changes to published workflows or actions need a bigger release than the pull request declares. |
FP811 | impact-declaration-conflict | 🔴 error | Another source declares a bigger impact than the one the release tool reads. |
FP812 | impact-over-declared | 🔵 info | The pull request declares a bigger impact than its workflow and action changes require. |
FP813 | impact-undeclared | 🔵 info | No release impact is declared; flowpact reports the impact the changes require. |
FP814 | impact-uncertain | 🟡 warning | A change to a published unit depends on something flowpact cannot evaluate statically. |
Config & overrides (FP9xx)
| Code | Name | Default | Summary |
|---|---|---|---|
FP901 | override-expired | 🔴 error | An override passed its expires date; the findings it suppressed are reported again. |
FP902 | override-unused | 🟡 warning | An override matches no finding — the problem was fixed, or the target is misspelled. |
FP903 | override-expiring-soon | 🔵 info | An override expires within 14 days. |
Reserved ranges
FP7xx— hygiene rules (reserved).FP8xx— contract drift (contract-missing,contract-stale,breaking-interface-change), shipping withflowpact check.FP9xx— config and overrides (override-expired,override-unused,invalid-config), shipping with overrides.