Tools Thicket Logo Tools Thicket

Browser-local checker

GitHub Actions Workflow Validator

Paste a .github/workflows/*.yml file into this GitHub Actions workflow validator to check its supported YAML syntax, then review selected workflow structure errors and warnings in your browser.

YAML syntax result

Checking…

Issue summary

0 errors, 0 warnings

Diagnostics

Documented limitations

This is a YAML subset parser. Anchors and aliases, tags, and document markers are unsupported. It does not check full YAML support, action existence, action input parameters, network validation, or complete cron semantics.

Workflow guidance

Common hosted runners include ubuntu-latest, windows-latest, and macos-latest. Common events are push, pull_request, workflow_dispatch, and schedule.

Use least-privilege permissions: contents: read, protect secrets.GITHUB_TOKEN, use a concurrency group to prevent duplicate runs, and use matrix strategy for variants.

Private by design

Your workflow text is parsed and checked in this browser. There is no network validation and no GitHub API verification.

Validate a workflow in three steps

  1. Paste your workflow YAML into the Workflow editor.
  2. Read the YAML syntax result and the issue summary.
  3. Review each diagnostic by severity, line, column, and message, then edit and check again.

The page starts with a clean example containing push and workflow_dispatch triggers, two jobs, a needs dependency, a matrix strategy, permissions: {contents: read}, and actions/checkout@v4. Select Restore example to load the example again.

What this GitHub Actions workflow checker checks

YAML syntax

The dependency-free parser supports this documented YAML subset:

  • Block mappings and block sequences
  • Plain scalars, single-quoted strings, and double-quoted strings
  • Line comments outside quoted strings
  • Literal block scalars with |
  • Folded block scalars with >
  • Simple flow collections such as [push, workflow_dispatch] and {contents: read}

Syntax failures stop structural checks and report a concrete reason with a one-based line and column. Diagnostics can identify inconsistent indentation, tabs used for indentation, a missing mapping colon, a missing mapping value, an unclosed quote, an unclosed flow collection, or malformed flow syntax. Literal blocks retain line breaks; folded blocks join supported content lines with spaces.

Anchors and aliases, tags, and document markers such as --- are unsupported features. The parser reports these explicitly rather than silently treating them as valid YAML.

GitHub Actions workflow structure

After syntax parsing succeeds, the validator checks:

  • A top-level on trigger is present.
  • A top-level jobs mapping exists and is not empty.
  • A regular job has runs-on, unless it uses a reusable workflow through uses.
  • A regular job has a non-empty steps sequence.
  • Each step has exactly one of uses or run; both or neither produce an error.
  • Every needs reference names an existing job ID. Unknown references list the available job IDs.
  • Each on.schedule cron value contains exactly five whitespace-separated fields.
  • Cron numeric atoms are checked against minute 0–59, hour 0–23, day of month 1–31, month 1–12, and day of week 0–6. A complete * field and the implemented stepped wildcard form such as */15 are accepted.
  • A third-party uses reference without an @ref produces a warning about supply-chain ambiguity. Local paths, Docker references, and actions/* references are excluded from this warning.
  • ${{ expressions have a closing }} delimiter. This is closure detection only.
  • Unknown top-level keys produce a warning. The supported list is name, run-name, on, permissions, env, defaults, concurrency, and jobs.

Diagnostics show error or warning severity. A clean workflow explicitly shows No errors found and 0 errors, 0 warnings; the result area does not remain blank.

How the checks work

The parser normalizes carriage returns to line feeds, removes blank lines and comments outside quoted strings, and reads the document with a line cursor. At each block level, the first child indentation establishes the expected indentation for sibling entries. A different indentation is reported as an indentation problem instead of being silently reinterpreted.

For each schedule value, the validator performs the actual operation:

fields = cron.trim().split(/\s+/)

The result must contain exactly five fields in this order: minute, hour, day of month, month, and day of week. Each field must use the implemented basic character form containing digits, commas, asterisks, slashes, and hyphens. The exact token * is recognized as a symbolic wildcard before numeric atom checks. Numeric atoms are then compared with the inclusive ranges listed above. This is a basic field check: it does not calculate a next run or validate complete cron grammar, calendar combinations, time zones, or daylight-saving behavior.

For expressions, the validator scans scalar text from left to right. When it finds ${{, it searches for the next }}. If no closing delimiter exists, it reports expression is unclosed at the opening delimiter. It does not evaluate expression syntax or values.

The issue summary counts emitted diagnostics:

summary = `${errors} errors, ${warnings} warnings`

The pass state is based on the error count. Warnings remain visible when there are no errors.

Workflow terms in the example and guidance

runs-on selects a runner label such as ubuntu-latest, windows-latest, or macos-latest. Common trigger names include push, pull_request, workflow_dispatch, and schedule.

A minimal permission example is permissions: {contents: read}. Workflows may also use secrets.GITHUB_TOKEN, a concurrency group to prevent duplicate runs, and a strategy.matrix value to run job variants. The page displays these terms in its example or guidance; it does not verify secret availability, runner availability, or remote action behavior.

Documented limitations

This is a dependency-free YAML subset parser, not a full YAML implementation and not a complete GitHub Actions validator. It does not implement every YAML scalar, flow, quoting, or block-scalar option. Anchors and aliases using & or *, tags beginning with !, and document markers such as --- are unsupported and produce explicit diagnostics.

The validator does not make network requests, execute workflows, verify that an action exists, inspect action input parameters, validate the GitHub API, evaluate expressions, or provide complete cron semantics. An @ref warning checks only whether a reference is present; it does not prove that the ref is immutable or safe.

Frequently asked questions

What does a GitHub Actions workflow validator check?

It checks the supported YAML subset and selected workflow rules, including required on and jobs, job runners and steps, needs IDs, basic five-field schedules, action reference warnings, unclosed expressions, and unknown top-level keys.

Is 0 3 * * * a valid GitHub Actions schedule?

The tool's basic checker accepts 0 3 * * *. It recognizes each bare * as a wildcard and reports no cron errors when the surrounding workflow is otherwise valid.

Does the validator support */15 * * * *?

Yes. The implemented basic cron checker accepts stepped wildcards such as */15 and checks the resulting numeric atoms and field count.

Does it validate all cron behavior?

No. It checks five fields, supported characters, and basic numeric ranges. It does not simulate calendars, calculate the next run, handle time zones or daylight-saving behavior, or verify GitHub's actual scheduler.

Why does a schedule value often appear in quotes?

Quoting keeps cron punctuation such as * as a YAML scalar in the workflow document. The validator checks the parsed schedule value and does not require one particular quoting style.

Does it upload my workflow or verify GitHub actions online?

No. Parsing and checks run in the browser. The tool does not contact GitHub to confirm action existence, validate action input parameters, or perform network verification.

What happens for 60 24 0 13 7?

The numeric boundary checks remain strict. The validator reports out-of-range errors for minute and hour, along with the corresponding invalid day-of-month, month, and day-of-week values.

What is required for a normal job?

A regular job requires runs-on and a non-empty steps sequence. A job with a reusable workflow uses reference is exempt from those two checks.