Skip to content

Rules ​

Every diagnostic of jactionlint has a stable ID such as unpinned-uses. IDs are never renamed or reused, so they are safe to write in the configuration, in ignore comments and in CI annotations. The ID of a finding is in the id field of --format json, in the ruleId of --format sarif and at the end of each finding of the text format.

Each rule has:

  • a group: correctness (mistakes which make a workflow fail or misbehave), security (insecure constructs), policy (good practices which are not mistakes by themselves) or style.
  • a default level: error, warn or info. Only errors make jactionlint exit with status 1 unless --strict-exit is given.
  • a profile: the first profile which enables the rule. There are three, and each includes the rules of the one before it: correctness (what actionlint checks and the bug detectors of jactionlint), default (adds the security posture and policy rules, and is used when no profile is configured) and pedantic (adds the noisy and opinionated rules). Rules which no profile enables run only when the configuration turns them on, and the rules marked "only with --online" run with that flag whatever the profile is. The profile comes from the profile key of the configuration or the --profile flag.
  • a pedantic option: a few audits report their noisier findings too when the option pedantic is true. It is true under the pedantic profile and false otherwise, and rules: {<id>: {pedantic: true}} turns it on for one audit.

The rules of the security, policy and style groups do not look at a job or a step whose if: is the literal false, because it never runs. The rules of the correctness group still do: a mistake in it breaks the file whether it runs or not.

yaml
# .github/jactionlint.yaml
profile: pedantic
rules:
  unpinned-uses: warn # lower the level
  require-shell: off # turn a rule off
IDGroupDefault levelProfile
action-syntaxcorrectnesserrorcorrectness
adhoc-packagessecurityerrordefault
agentic-actionssecurityerrordefault
anonymous-definitionpolicywarnpedantic
archived-usessecuritywarnonly with --online
artipackedsecurityerrordefault
background-step-not-waitedcorrectnesserrorcorrectness
bot-conditionssecurityerrordefault
cache-poisoningsecurityerrordefault
checkout-static-credentialssecurityerrordefault
concurrency-cancels-prscorrectnesserrordefault
concurrency-cancels-releasecorrectnesserrordefault
concurrency-limitspolicyerrordefault
conflicting-runner-labelscorrectnesserrorcorrectness
constant-conditioncorrectnesserrorcorrectness
context-availabilitycorrectnesserrorcorrectness
continue-on-errorpolicyinfopedantic
cron-too-frequentcorrectnesserrorcorrectness
cyclic-job-needscorrectnesserrorcorrectness
dangerous-triggerssecurityerrordefault
dependabot-cooldownsecurityerrordefault
dependabot-executionsecurityerrordefault
dependabot-missing-actions-updatepolicywarnpedantic
dependabot-syntaxcorrectnesserrorcorrectness
deprecated-action-inputcorrectnesserrorcorrectness
deprecated-commandscorrectnesserrorcorrectness
duplicate-job-idcorrectnesserrorcorrectness
duplicate-job-needscorrectnesserrorcorrectness
duplicate-keycorrectnesserrorcorrectness
duplicate-step-idcorrectnesserrorcorrectness
duplicate-triggerspolicyerrordefault
excessive-permissionssecurityerrordefault
expired-ignorepolicyerrorcorrectness
expression-syntaxcorrectnesserrorcorrectness
expression-typecorrectnesserrorcorrectness
forbidden-usespolicyerroronly when configured
gate-job-skipped-on-failurecorrectnesserrordefault
github-appsecurityerrordefault
github-envsecurityerrordefault
hardcoded-container-credentialssecurityerrorcorrectness
if-always-truecorrectnesserrorcorrectness
impostor-commitsecurityerroronly with --online
insecure-commandssecurityerrordefault
insecure-ssh-keyscansecurityerrordefault
insecure-url-schemesecurityerrordefault
invalid-activity-typecorrectnesserrorcorrectness
invalid-croncorrectnesserrorcorrectness
invalid-env-var-namecorrectnesserrorcorrectness
invalid-event-configcorrectnesserrorcorrectness
invalid-event-filtercorrectnesserrorcorrectness
invalid-function-callcorrectnesserrorcorrectness
invalid-globcorrectnesserrorcorrectness
invalid-idcorrectnesserrorcorrectness
invalid-ignore-commentcorrectnesserrorcorrectness
invalid-label-patterncorrectnesserrorcorrectness
invalid-local-actioncorrectnesserrorcorrectness
invalid-local-workflowcorrectnesserrorcorrectness
invalid-parallel-stepcorrectnesserrorcorrectness
invalid-permissionscorrectnesserrorcorrectness
invalid-shell-namecorrectnesserrorcorrectness
invalid-timezonecorrectnesserrorcorrectness
invalid-usescorrectnesserrorcorrectness
invalid-workflow-callcorrectnesserrorcorrectness
invalid-workflow-call-inputcorrectnesserrorcorrectness
invalid-workflow-dispatch-inputcorrectnesserrorcorrectness
invisible-characterssecurityerrordefault
known-vulnerable-actionssecurityerroronly with --online
local-action-checkoutcorrectnesserrorcorrectness
matrix-duplicate-valuecorrectnesserrorcorrectness
matrix-invalid-excludecorrectnesserrorcorrectness
max-run-linesstyleerrorpedantic
merge-keycorrectnesserrorcorrectness
misfeaturesecurityerrordefault
missing-action-inputcorrectnesserrorcorrectness
missing-permissionspolicyerrordefault
missing-timeoutpolicyerrordefault
missing-workflow-inputcorrectnesserrorcorrectness
missing-workflow-secretcorrectnesserrorcorrectness
mutable-runner-labelpolicywarnpedantic
obfuscationsecurityerrordefault
outdated-action-runnercorrectnesserrorcorrectness
overprovisioned-secretssecurityerrordefault
pipeline-without-pipefailcorrectnesserrordefault
pyflakescorrectnesserrorcorrectness
recursive-aliascorrectnesserrorcorrectness
ref-confusionsecuritywarnonly with --online
ref-version-mismatchsecuritywarnonly with --online
require-expression-wrappingstyleerrorpedantic
require-shellstyleerrorpedantic
required-actionspolicyerroronly when configured
secrets-inheritsecurityerrordefault
secrets-outside-envsecuritywarnpedantic
self-hosted-runnersecurityinfopedantic
self-repositorysecurityinfopedantic
shellcheckcorrectnesserrorcorrectness
stale-action-refssecurityinfoonly with --online
superfluous-actionssecurityerrordefault
template-injectionsecurityerrorcorrectness
timeout-too-longpolicyerroronly when configured
typosquat-usessecurityerrordefault
undefined-functioncorrectnesserrorcorrectness
undefined-job-needscorrectnesserrorcorrectness
undefined-propertycorrectnesserrorcorrectness
undocumented-permissionspolicyinfopedantic
unknown-action-inputcorrectnesserrorcorrectness
unknown-eventcorrectnesserrorcorrectness
unknown-runner-labelcorrectnesserrorcorrectness
unknown-workflow-inputcorrectnesserrorcorrectness
unknown-workflow-secretcorrectnesserrorcorrectness
unlocked-installsecurityerrordefault
unpinned-imagessecurityerrordefault
unpinned-toolssecurityerrordefault
unpinned-usespolicyerrordefault
unredacted-secretssecurityerrordefault
unsound-containssecurityerrordefault
unsound-prefix-matchsecurityerrordefault
unsound-ternarycorrectnesserrorcorrectness
untrusted-artifactsecurityerrordefault
untrusted-checkoutsecurityerrordefault
unused-anchorcorrectnesserrorcorrectness
unused-baseline-entrypolicyinfocorrectness
unused-ignorepolicyerrorpedantic
unused-job-outputpolicyerrordefault
unused-needsstyleinfopedantic
unused-workflow-inputpolicywarnpedantic
unverified-downloadsecurityerrordefault
use-trusted-publishingsecurityerrordefault
workflow-call-permissionscorrectnesserrorcorrectness
workflow-input-typecorrectnesserrorcorrectness
workflow-run-namescorrectnesserrorcorrectness
workflow-secret-scopesecuritywarnpedantic
workflow-syntaxcorrectnesserrorcorrectness
yaml-syntaxcorrectnesserrorcorrectness

action-syntax ​

The action metadata does not follow the syntax of action.yml.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

adhoc-packages ​

A package is installed by name with npm, yarn, pnpm, bun, gem or bundle add outside of a lock file.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

agentic-actions ​

An AI agent action can be steered by outsiders, runs on code of a pull request, or has its safeguards turned off.

  • Group: security
  • Default level: error
  • Profile: default
  • Option any-trigger (bool, default false): Also report the unsafe settings of an agent (tools that allow any command, permission checks switched off) in a workflow that no outsider can trigger.
  • Details and examples: checks

anonymous-definition ​

A workflow has no top-level name:.

  • Group: policy
  • Default level: warn
  • Profile: pedantic
  • Fixable: yes
  • Details and examples: checks

archived-uses ​

An action or reusable workflow is in an archived repository.

  • Group: security
  • Default level: warn
  • Profile: only with --online
  • Needs network access: yes (only with --online)
  • Details and examples: checks

artipacked ​

actions/checkout persists the GITHUB_TOKEN credential in the git config.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

background-step-not-waited ​

Outputs or results of a background step are read before a wait step covers it.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

bot-conditions ​

A condition trusts a bot by github.actor, which can be spoofed.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

cache-poisoning ​

A cache is restored in a release job or written by a privileged trigger.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

checkout-static-credentials ​

actions/checkout is given an SSH key or a token that does not expire.

  • Group: security
  • Default level: error
  • Profile: default
  • Option secret-tokens (bool, no default): Also report a token input taken from a secret other than GITHUB_TOKEN (a personal access token). The ssh-key input is always reported. Unset, it is on under the pedantic profile and off otherwise.
  • Option allow (strings, empty by default): Names of secrets which may be given to actions/checkout (for example a deploy key).
  • Details and examples: checks

concurrency-cancels-prs ​

A concurrency group that cancels runs is shared by all pull requests, so unrelated pull requests cancel each other.

  • Group: correctness
  • Default level: error
  • Profile: default
  • Details and examples: checks

concurrency-cancels-release ​

cancel-in-progress can cancel a release or a deployment which is still running.

  • Group: correctness
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

concurrency-limits ​

A workflow does not cancel superseded runs with concurrency:.

  • Group: policy
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

conflicting-runner-labels ​

The runner labels of a job conflict with each other.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

constant-condition ​

An if: condition is a constant expression.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

context-availability ​

A context or special function is used where it is not available.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

continue-on-error ​

A job has continue-on-error: true, so its failure does not fail the workflow.

  • Group: policy
  • Default level: info
  • Profile: pedantic
  • Option steps (bool, default false): Also report steps with continue-on-error: true. By default only jobs are reported.
  • Details and examples: checks

cron-too-frequent ​

A scheduled job runs more often than once every 5 minutes.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

cyclic-job-needs ​

Jobs depend on each other in a cycle.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

dangerous-triggers ​

A workflow uses pull_request_target, workflow_run or issue_comment.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

dependabot-cooldown ​

An update in dependabot.yml has no cooldown or a cooldown shorter than the minimum.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Option days (int, default 7): The minimum number of days "cooldown.default-days" must be. Defaults to 7.
  • Option default-days (int, no default): The number of days --fix writes as "cooldown.default-days". It must be at least "days". There is no default: without it findings have no fix.
  • Details and examples: checks

dependabot-execution ​

An update in dependabot.yml allows insecure external code execution.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

dependabot-missing-actions-update ​

dependabot.yml has no github-actions update although the repository has workflows using actions.

  • Group: policy
  • Default level: warn
  • Profile: pedantic
  • Details and examples: checks

dependabot-syntax ​

The Dependabot configuration does not follow the syntax of dependabot.yml.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

deprecated-action-input ​

A deprecated input of an action is used.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

deprecated-commands ​

A deprecated workflow command such as ::set-output is used.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

duplicate-job-id ​

A job ID is defined more than once.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

duplicate-job-needs ​

A job ID is listed more than once in needs.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

duplicate-key ​

A key is defined more than once in a mapping.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

duplicate-step-id ​

A step ID is not unique within its job.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

duplicate-triggers ​

push and pull_request both run the workflow for the same commit.

  • Group: policy
  • Default level: error
  • Profile: default
  • Details and examples: checks

excessive-permissions ​

The GITHUB_TOKEN gets write access that is broader than needed.

  • Group: security
  • Default level: error
  • Profile: default
  • Option require-workflow-permissions (bool, default false): Also report a workflow which has no top-level permissions, even when its jobs set their own.
  • Details and examples: checks

expired-ignore ​

An entry of "ignores" in the config file has expired or is about to.

  • Group: policy
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

expression-syntax ​

A ${{ }} expression has a syntax error.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

expression-type ​

A ${{ }} expression has a type error.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

forbidden-uses ​

An action or reusable workflow is not allowed or is denied by the configuration.

  • Group: policy
  • Default level: error
  • Profile: only when configured
  • Option allow (strings, empty by default): Patterns of the only actions and reusable workflows which may be used, e.g. "actions/*". The rule does nothing without allow or deny.
  • Option deny (strings, empty by default): Patterns of actions and reusable workflows which must not be used.
  • Details and examples: checks

gate-job-skipped-on-failure ​

A job that reads the results of the jobs it needs is skipped when one of them fails.

  • Group: correctness
  • Default level: error
  • Profile: default
  • Details and examples: checks

github-app ​

A GitHub App token is issued with more access or a longer life than needed.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

github-env ​

Input that an outsider controls, or a value that is not a literal in a workflow triggered by pull_request_target or workflow_run, is written to GITHUB_ENV or GITHUB_PATH.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

hardcoded-container-credentials ​

A password for a container registry is written directly in the workflow.

  • Group: security
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

if-always-true ​

An if: condition is always true because of the characters around ${{ }}.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

impostor-commit ​

A hash-pinned action uses a commit which is not part of the repository's own history (it exists only in a fork).

  • Group: security
  • Default level: error
  • Profile: only with --online
  • Needs network access: yes (only with --online)
  • Option max-branches (int, default 1000): How many branches of the action repository a commit is compared with before giving up without a verdict. Without a token each branch costs a request, so at most 100 are compared.
  • Details and examples: checks

insecure-commands ​

ACTIONS_ALLOW_UNSECURE_COMMANDS enables the deprecated set-env and add-path commands.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

insecure-ssh-keyscan ​

ssh-keyscan output is trusted as the host key without verification.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

insecure-url-scheme ​

A download uses http, ftp or git instead of https.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

invalid-activity-type ​

An activity type is not available for the Webhook event.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-cron ​

A cron schedule has an invalid format.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-env-var-name ​

An environment variable name contains characters which are not allowed.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-event-config ​

An event is configured with options it does not support.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-event-filter ​

An event filter is not available for the event or conflicts with another filter.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-function-call ​

A built-in function is called with wrong arguments.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-glob ​

A glob filter pattern is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-id ​

A job or step ID does not follow the naming convention.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-ignore-comment ​

An inline ignore comment is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-label-pattern ​

A runner label pattern in the configuration is not a valid glob.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-local-action ​

A local action cannot be loaded or its metadata is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-local-workflow ​

A local reusable workflow cannot be loaded or is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-parallel-step ​

A step is not allowed inside a parallel group or refers to a wrong step.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-permissions ​

A permission scope or its value is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-shell-name ​

A shell name is not available on the runner.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-timezone ​

A timezone of a schedule is not a valid IANA timezone name.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-uses ​

A uses: value does not follow the format of an action or a Docker image.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-workflow-call ​

A reusable workflow call does not follow the format of a reusable workflow.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-workflow-call-input ​

An input of the workflow_call event is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invalid-workflow-dispatch-input ​

An input of the workflow_dispatch event is invalid.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

invisible-characters ​

A file contains an invisible or bidirectional control character which hides what the text says.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

known-vulnerable-actions ​

An action version is affected by a published GitHub security advisory.

  • Group: security
  • Default level: error
  • Profile: only with --online
  • Needs network access: yes (only with --online)
  • Option allow (strings, empty by default): Advisory IDs (GHSA-...) which are not reported.
  • Details and examples: checks

local-action-checkout ​

A local action is used before any step checks out the repository.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

matrix-duplicate-value ​

A matrix has a duplicate value.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

matrix-invalid-exclude ​

An exclude entry of a matrix does not match the matrix.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

max-run-lines ​

A run: script has more lines than allowed.

  • Group: style
  • Default level: error
  • Profile: pedantic
  • Option max (int, default 100): The maximum number of non-blank lines of a run: script.
  • Details and examples: checks

merge-key ​

The YAML merge key << is used, which GitHub Actions does not support.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

misfeature ​

A misfeature of GitHub Actions is used: the pip-install input of setup-python or the cmd shell. With the option pedantic, a shell that GitHub does not document too.

  • Group: security
  • Default level: error
  • Profile: default
  • Option pedantic (bool, no default): Also report the pedantic checks, which are noisier. Unset, they run under the pedantic profile.
  • Details and examples: checks

missing-action-input ​

A required input of an action is not specified.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

missing-permissions ​

Neither the workflow nor the job sets permissions:.

  • Group: policy
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

missing-timeout ​

A job does not set timeout-minutes.

  • Group: policy
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Option default-minutes (int, no default): The timeout-minutes which --fix adds to a job. There is no default: the rule has no fix unless this is set. It is lowered to the max of timeout-too-long when that is smaller.
  • Details and examples: checks

missing-workflow-input ​

A required input of a reusable workflow is not specified.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

missing-workflow-secret ​

A required secret of a reusable workflow is not passed.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

mutable-runner-label ​

A runner label is an alias that GitHub moves to newer images, such as ubuntu-latest.

  • Group: policy
  • Default level: warn
  • Profile: pedantic
  • Fixable: yes
  • Option pin (string-map, no default): Maps a moving label to the fixed label that --fix writes in its place, e.g. ubuntu-latest: ubuntu-24.04. There is no default: without an entry the finding has no fix.
  • Details and examples: checks

obfuscation ​

A path at uses: or an expression is written in an obfuscated way.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

outdated-action-runner ​

An action runs on a runtime which GitHub Actions no longer supports.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

overprovisioned-secrets ​

An expression uses the whole secrets context.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

pipeline-without-pipefail ​

A failing command in a pipeline of a run: script is hidden because the shell does not enable pipefail.

  • Group: correctness
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Details and examples: checks

pyflakes ​

pyflakes reported an issue in a Python script.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

recursive-alias ​

A YAML alias refers to itself.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

ref-confusion ​

The ref of an action is both a branch and a tag of its repository.

  • Group: security
  • Default level: warn
  • Profile: only with --online
  • Needs network access: yes (only with --online)
  • Details and examples: checks

ref-version-mismatch ​

The version comment of a hash-pinned action does not match the pinned commit.

  • Group: security
  • Default level: warn
  • Profile: only with --online
  • Needs network access: yes (only with --online)
  • Details and examples: checks

require-expression-wrapping ​

An if: condition is not wrapped in ${{ }}.

  • Group: style
  • Default level: error
  • Profile: pedantic
  • Details and examples: checks

require-shell ​

A run: step does not set the shell explicitly.

  • Group: style
  • Default level: error
  • Profile: pedantic
  • Details and examples: checks

required-actions ​

An action listed in required-actions is not used by a workflow.

  • Group: policy
  • Default level: error
  • Profile: only when configured

secrets-inherit ​

A reusable workflow is called with secrets: inherit.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

secrets-outside-env ​

A job uses a secret but has no environment.

  • Group: security
  • Default level: warn
  • Profile: pedantic
  • Option allow (strings, empty by default): Names of secrets which may be used outside of an environment. GITHUB_TOKEN is always allowed.
  • Details and examples: checks

self-hosted-runner ​

A job runs on a self-hosted runner.

  • Group: security
  • Default level: info
  • Profile: pedantic
  • Details and examples: checks

self-repository ​

A local action or workflow is referenced as ./path instead of $/path.

  • Group: security
  • Default level: info
  • Profile: pedantic
  • Fixable: yes
  • Details and examples: checks

shellcheck ​

shellcheck reported an issue in a shell script.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

stale-action-refs ​

A hash-pinned action uses a commit which no tag of the repository points to.

  • Group: security
  • Default level: info
  • Profile: only with --online
  • Needs network access: yes (only with --online)
  • Details and examples: checks

superfluous-actions ​

An action does what a tool of the runner image does as well, such as gh release create.

  • Group: security
  • Default level: error
  • Profile: default
  • Option pedantic (bool, no default): Also report the pedantic checks, which are noisier. Unset, they run under the pedantic profile.
  • Details and examples: checks

template-injection ​

A potentially untrusted input is expanded in a script, a container option or the prompt of an AI agent. With the option pedantic, so is any other expression.

  • Group: security
  • Default level: error
  • Profile: correctness
  • Fixable: yes
  • Option pedantic (bool, no default): Also report the pedantic checks, which are noisier. Unset, they run under the pedantic profile.
  • Details and examples: checks

timeout-too-long ​

timeout-minutes of a job exceeds the configured maximum.

  • Group: policy
  • Default level: error
  • Profile: only when configured
  • Option max (number, no default): The maximum allowed timeout-minutes. The rule does nothing without it.
  • Details and examples: checks

typosquat-uses ​

An action is one typo away from a popular action of another owner.

  • Group: security
  • Default level: error
  • Profile: default
  • Option allow (strings, empty by default): Slugs (owner/repo) of actions which are never reported, e.g. a legitimate fork.
  • Details and examples: checks

undefined-function ​

An undefined function is called in an expression.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

undefined-job-needs ​

A job needs a job which does not exist.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

undefined-property ​

An undefined variable or property is accessed in an expression.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

undocumented-permissions ​

A permission scope above read has no comment explaining it.

  • Group: policy
  • Default level: info
  • Profile: pedantic
  • Option include-read (bool, default false): Also require a comment for scopes granted with read, except contents: read.
  • Details and examples: checks

unknown-action-input ​

An input which the action does not define is specified.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

unknown-event ​

An unknown Webhook event is used.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

unknown-runner-label ​

A runner label is unknown.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

unknown-workflow-input ​

An input which the reusable workflow does not define is specified.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

unknown-workflow-secret ​

A secret which the reusable workflow does not define is passed.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

unlocked-install ​

cargo install runs without --locked, or npm, yarn or pnpm install without freezing a lock file that the repository has.

  • Group: security
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Option pedantic (bool, no default): Also report the pedantic checks, which are noisier. Unset, they run under the pedantic profile.
  • Details and examples: checks

unpinned-images ​

A container or service image is not pinned by a digest.

  • Group: security
  • Default level: error
  • Profile: default
  • Option require-digest (bool, default true): Report images pinned by a tag other than latest too. Turn it off to report only images without a tag or with the latest tag.
  • Details and examples: checks

unpinned-tools ​

An action installs the newest version of its tool because no version is set or it is latest.

  • Group: security
  • Default level: error
  • Profile: default
  • Option pedantic (bool, no default): Also report the pedantic checks, which are noisier. Unset, they run under the pedantic profile.
  • Details and examples: checks

unpinned-uses ​

An action, reusable workflow or Docker image is not pinned to a commit SHA or digest.

  • Group: policy
  • Default level: error
  • Profile: default
  • Fixable: yes
  • Option policies (string-map, default empty): How strongly to pin the actions matching a pattern: hash-pin (full commit SHA, the default for everything), ref-pin (any tag, branch or SHA) or any. The most specific pattern wins. Patterns are "", "owner/", "owner/repo" and "owner/repo/path". Docker images follow the "*" policy.
  • Details and examples: checks

unredacted-secrets ​

A secret is parsed with fromJSON(), so the fields of it are not redacted in logs.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

unsound-contains ​

A condition uses contains() on a string literal, which also matches substrings.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

unsound-prefix-match ​

An account, an owner or a repository is identified by a prefix, a suffix or a part of its name.

  • Group: security
  • Default level: error
  • Profile: default
  • Option refs (bool, default false): Also check the names of branches and tags (github.ref, github.head_ref, ...). A prefix test of a ref is often meant, so this is noisy.
  • Details and examples: checks

unsound-ternary ​

The a && b || c idiom has a falsy b so it always evaluates to c.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

untrusted-artifact ​

A workflow_run workflow uses an artifact of the triggering run without validating it.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

untrusted-checkout ​

A pull_request_target or workflow_run workflow checks out the code of a pull request and runs it.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

unused-anchor ​

A YAML anchor is defined but never used.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

unused-baseline-entry ​

A baseline entry matches no finding any more, so the baseline can shrink.

  • Group: policy
  • Default level: info
  • Profile: correctness

unused-ignore ​

An ignore comment or an entry of "ignores" in the config file did not suppress anything.

  • Group: policy
  • Default level: error
  • Profile: pedantic
  • Fixable: yes
  • Option zizmor (bool, default false): Also report "# zizmor: ignore[...]" comments which suppressed nothing. Turn it on after zizmor is gone.
  • Details and examples: checks

unused-job-output ​

An output of a job is never read by another job or by a workflow_call output.

  • Group: policy
  • Default level: error
  • Profile: default
  • Details and examples: checks

unused-needs ​

A needs entry is neither read by the job nor needed for the order of jobs.

  • Group: style
  • Default level: info
  • Profile: pedantic
  • Details and examples: checks

unused-workflow-input ​

An input of workflow_dispatch or workflow_call is never used.

  • Group: policy
  • Default level: warn
  • Profile: pedantic
  • Details and examples: checks

unverified-download ​

A script runs what it downloads without verifying it.

  • Group: security
  • Default level: error
  • Profile: default
  • Option allow (strings, empty by default): Hosts, or URL prefixes (entries with "😕/"), whose downloads are accepted without verification.
  • Details and examples: checks

use-trusted-publishing ​

A package is published with a long-lived credential although the registry supports trusted publishing.

  • Group: security
  • Default level: error
  • Profile: default
  • Details and examples: checks

workflow-call-permissions ​

A caller job grants fewer permissions than a reusable workflow requires.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

workflow-input-type ​

The type of a value passed to a reusable workflow does not match its input.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

workflow-run-names ​

A workflow_run event refers to a workflow which does not exist in the repository.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

workflow-secret-scope ​

A secret is assigned to the workflow-level env and reaches multiple jobs.

  • Group: security
  • Default level: warn
  • Profile: pedantic
  • Details and examples: checks

workflow-syntax ​

The workflow does not follow the syntax of GitHub Actions workflows.

  • Group: correctness
  • Default level: error
  • Profile: correctness
  • Details and examples: checks

yaml-syntax ​

The file is not valid YAML.

  • Group: correctness
  • Default level: error
  • Profile: correctness

Retired rule IDs ​

An audit is one rule with one ID. These IDs existed while 2.0 was in development, before the first release, and were merged into the rule that reports their findings now. --ignore, the ignore lists of paths and the # jactionlint ignore= comments still take them: such an ignore matches only the findings that had the old ID, and jactionlint warns that the ID is deprecated. rules, ignores, fix.rules and --fix-rules do not take them.

Retired IDRuleFindings are on with
github-env-untrusted-inputgithub-envalways
misfeature-custom-shellmisfeaturethe option pedantic
template-injection-expansiontemplate-injectionthe option pedantic
template-injection-trustedtemplate-injectionthe option pedantic
MIT LicenseCopyright © 2026jdx.dev