Skip to main content

require-run-step-timeout

Rule catalog ID: R115

Targeted pattern scopeโ€‹

Non-reusable workflow jobs under jobs.<job_id> that contain steps[*].run commands.

What this rule reportsโ€‹

This rule reports jobs that contain run steps but do not define timeout-minutes at the job level.

Why this rule existsโ€‹

run: steps (shell commands) can hang indefinitely while waiting on network I/O, stdin input, or a deadlocked subprocess. A hung step consumes the entire job's timeout budget. Explicit job-level timeouts prevent unattended runners from consuming resources indefinitely and reduce incident response time.

โŒ Incorrectโ€‹

jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm install
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test

โœ… Correctโ€‹

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- run: npm install
jobs:
checkout-only:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
jobs:
ci:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- run: npm test

Additional examplesโ€‹

โœ… Correct โ€” Jobs without run steps don't need timeoutsโ€‹

jobs:
dispatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/upload-artifact@v3

โœ… Correct โ€” Reusable workflows are skippedโ€‹

jobs:
reusable-call:
uses: ./.github/workflows/shared.yml
with:
timeout: 20

ESLint flat config exampleโ€‹

import githubActionsPlugin from "eslint-plugin-github-actions";

export default [
{
plugins: { "github-actions": githubActionsPlugin },
rules: {
"github-actions/require-run-step-timeout": "error",
},
},
];

When not to use itโ€‹

Disable this rule if:

  • Your workflows never use run steps (only actions)
  • You enforce timeouts via external mechanisms (e.g., runner configuration, workflow policies)
  • Your GitHub plan does not support runner group settings and explicit timeouts are not a concern

Further readingโ€‹