{"record":{"id":"c0672f2da0dab9b0","repo":"cli/cli","slug":"invalid-workflow-no-on-key","errorCode":null,"errorMessage":"invalid workflow: no 'on' key","messagePattern":"invalid workflow: no 'on' key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/workflow/run/run.go","lineNumber":464,"sourceCode":"\t\t\t\t\t\tdispatchKeyNode = node\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if node.Kind == yaml.ScalarNode {\n\t\t\t\tif node.Value == \"workflow_dispatch\" {\n\t\t\t\t\tdispatchKeyNode = node\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif strings.EqualFold(node.Value, \"on\") {\n\t\t\tonKeyNode = node\n\t\t}\n\t}\n\n\tif onKeyNode == nil {\n\t\treturn nil, errors.New(\"invalid workflow: no 'on' key\")\n\t}\n\n\tif dispatchKeyNode == nil {\n\t\treturn nil, errors.New(\"unable to manually run a workflow without a workflow_dispatch event\")\n\t}\n\n\tout := []WorkflowInput{}\n\n\tm := map[string]WorkflowInput{}\n\n\tif inputsKeyNode == nil || inputsMapNode == nil {\n\t\treturn out, nil\n\t}\n\n\terr = inputsMapNode.Decode(&m)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not decode workflow inputs: %w\", err)\n\t}","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/cli/cli/blob/0eeec0b92edbe70199f9768522f831d3534f41ad/pkg/cmd/workflow/run/run.go#L446-L482","documentation":"Deeper in the same parser of `gh workflow run`: the single YAML document parsed, but scanning its top-level mapping keys (case-insensitively, since YAML 1.1 treats on/unquoted-true alike) found no 'on' key. GitHub requires `on:` to define triggers; a workflow without it is invalid, and gh cannot locate workflow_dispatch inputs without it.","triggerScenarios":"Workflow file's root mapping contains keys like name/jobs but no 'on' (or ON/On). Note the parser compares strings.EqualFold(node.Value, \"on\") across scalar keys; a missing or misspelled key (e.g. 'trigger:') yields onKeyNode == nil. Follow-up error 'unable to manually run a workflow without a workflow_dispatch event' fires when `on` exists but lacks workflow_dispatch.","commonSituations":"Renaming `on:` to something else by mistake; quoting issues where 'on' became part of another structure; porting from other CI systems; YAML where `on:` line lost its colon.","solutions":["Add the trigger block with workflow_dispatch: `on: {workflow_dispatch: {inputs: ...}}`.","Run actionlint on the workflow to catch structural errors before pushing.","Verify with `yq '.keys' .github/workflows/x.yml` that 'on' is a top-level key.","Remember `gh workflow run` requires the workflow_dispatch trigger specifically."],"exampleFix":"# before (.github/workflows/deploy.yml)\nname: deploy\njobs:\n  build: {...}\n\n# after\nname: deploy\non:\n  workflow_dispatch:\n    inputs:\n      env: {description: target, required: true}\njobs:\n  build: {...}","handlingStrategy":"validation","validationCode":"yq 'has(\"on\")' .github/workflows/deploy.yml   # must print true\nyq '.on | has(\"workflow_dispatch\")' .github/workflows/deploy.yml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require `on: workflow_dispatch` for any workflow you drive with `gh workflow run`.","Run actionlint locally as a pre-commit hook for workflow files.","Remember `gh workflow run` cannot trigger scheduled/push-only workflows."],"tags":["yaml","workflow-run","validation","triggers","workflow-dispatch"],"backgroundTag":null,"analyzedSha":"0eeec0b92edbe70199f9768522f831d3534f41ad","analyzedAt":"2026-08-15T12:31:05.478Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}