{"record":{"id":"26349435dd4dcde2","repo":"nektos/act","slug":"workflow-is-not-valid-s-w","errorCode":null,"errorMessage":"workflow is not valid. '%s': %w","messagePattern":"workflow is not valid\\. '(.+?)': %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/planner.go","lineNumber":133,"sourceCode":"\t}\n\n\twp := new(workflowPlanner)\n\tfor _, wf := range workflows {\n\t\text := filepath.Ext(wf.workflowDirEntry.Name())\n\t\tif ext == \".yml\" || ext == \".yaml\" {\n\t\t\tf, err := os.Open(filepath.Join(wf.dirPath, wf.workflowDirEntry.Name()))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlog.Debugf(\"Reading workflow '%s'\", f.Name())\n\t\t\tworkflow, err := ReadWorkflow(f, strict)\n\t\t\tif err != nil {\n\t\t\t\t_ = f.Close()\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\treturn nil, fmt.Errorf(\"unable to read workflow '%s': file is empty: %w\", wf.workflowDirEntry.Name(), err)\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"workflow is not valid. '%s': %w\", wf.workflowDirEntry.Name(), err)\n\t\t\t}\n\t\t\t_, err = f.Seek(0, 0)\n\t\t\tif err != nil {\n\t\t\t\t_ = f.Close()\n\t\t\t\treturn nil, fmt.Errorf(\"error occurring when resetting io pointer in '%s': %w\", wf.workflowDirEntry.Name(), err)\n\t\t\t}\n\n\t\t\tworkflow.File = wf.workflowDirEntry.Name()\n\t\t\tif workflow.Name == \"\" {\n\t\t\t\tworkflow.Name = wf.workflowDirEntry.Name()\n\t\t\t}\n\n\t\t\terr = validateJobName(workflow)\n\t\t\tif err != nil {\n\t\t\t\t_ = f.Close()\n\t\t\t\treturn nil, err\n\t\t\t}\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/model/planner.go#L115-L151","documentation":"Generic wrapper returned when ReadWorkflow fails with anything other than io.EOF while parsing a workflow file from .github/workflows. The %w chain carries the real cause: YAML syntax errors, strict-mode schema violations, or unsupported node types. This is the planner path (directory scan); the file name is included.","triggerScenarios":"A workflow file with invalid YAML indentation, duplicate keys, tabs, or a structure failing schema validation in strict mode. Any parse error except plain EOF lands here.","commonSituations":"Hand-edited workflows with broken indentation; anchors/aliases used in ways resolveAliases cannot handle; running act with strict schema validation on workflows using undocumented keys; merge conflicts left unresolved in workflow files.","solutions":["Validate the file with a YAML linter or `yamllint .github/workflows/` first.","Read the wrapped error text — it contains the exact line/column from the YAML decoder.","If the error mentions schema validation, see https://nektosact.com/usage/schema.html and fix or remove the non-schema keys.","Re-run `act` with the same event to confirm the fixed file plans cleanly."],"exampleFix":"# before\njobs:\n  build:\n   runs-on: ubuntu-latest   # wrong indent\n# after\njobs:\n  build:\n    runs-on: ubuntu-latest","handlingStrategy":"try-catch","validationCode":"cmd := exec.Command(\"yamllint\", \"-d\", \"relaxed\", \".github/workflows/\")\nif err := cmd.Run(); err != nil { return fmt.Errorf(\"workflows failed lint: %w\", err) }","typeGuard":null,"tryCatchPattern":"plan, err := model.NewWorkflowPlanner(dir, strict)\nif err != nil {\n    var joined interface{ Unwrap() []error }\n    if errors.As(err, &joined) {\n        for _, e := range joined.Unwrap() { log.Error(e) } // schema details\n    }\n    return err\n}","preventionTips":["Lint every workflow change in CI before act sees it.","Keep indentation consistent (2 spaces) in workflow YAML.","Resolve merge conflicts in workflow files completely before running act."],"tags":["workflow","planner","yaml","validation"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}