{"record":{"id":"c9343bd80a1f0be6","repo":"nektos/act","slug":"sfailed-to-parse-s","errorCode":null,"errorMessage":"%sFailed to parse: %s","messagePattern":"(.+?)Failed to parse: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/schema/schema.go","lineNumber":218,"sourceCode":"}\n\nfunc (s *Node) checkExpression(node *yaml.Node) (bool, error) {\n\tval := node.Value\n\thadExpr := false\n\tvar err error\n\tfor {\n\t\tif i := strings.Index(val, \"${{\"); i != -1 {\n\t\t\tval = val[i+3:]\n\t\t} else {\n\t\t\treturn hadExpr, err\n\t\t}\n\t\thadExpr = true\n\n\t\tparser := actionlint.NewExprParser()\n\t\tlexer := actionlint.NewExprLexer(val)\n\t\texprNode, parseErr := parser.Parse(lexer)\n\t\tif parseErr != nil {\n\t\t\terr = errors.Join(err, fmt.Errorf(\"%sFailed to parse: %s\", formatLocation(node), parseErr.Message))\n\t\t\tcontinue\n\t\t}\n\t\tval = val[lexer.Offset():]\n\t\tcerr := s.checkSingleExpression(exprNode)\n\t\tif cerr != nil {\n\t\t\terr = errors.Join(err, fmt.Errorf(\"%s%w\", formatLocation(node), cerr))\n\t\t}\n\t}\n}\n\nfunc AddFunction(funcs *[]FunctionInfo, s string, i1, i2 int) {\n\t*funcs = append(*funcs, FunctionInfo{\n\t\tname: s,\n\t\tmin:  i1,\n\t\tmax:  i2,\n\t})\n}\n","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/schema/schema.go#L200-L236","documentation":"Error from Node.checkExpression (schema.go:218) when the text following a `${{` marker cannot be parsed as a valid expression by actionlint's expression parser. The location (line/column of the YAML node) is prefixed to the parser's message.","triggerScenarios":"Malformed expression syntax after ${{: unbalanced parentheses, stray operators, or leftover text like ${{ env.NAME extra }}. The loop finds each ${{ and parses everything up to the closing }}; a parse failure joins this error and continues scanning.","commonSituations":"Typos in complex expressions; YAML quoting issues that mangle ${{ }} (e.g. single-quote escaping turning '' into content); templating tools that partially substitute values leaving invalid syntax.","solutions":["Read the parser message after 'Failed to parse:' — it names the syntax problem and position","Fix the expression between ${{ and }} (balance parens, remove stray tokens)","Check YAML quoting: inside single quotes escape ' as '' and avoid double-substitution","Paste the expression into actionlint or the GitHub expression docs to verify syntax"],"exampleFix":"# before:\nif: ${{ env.FLAG == 'true' && (github.ref\n# after:\nif: ${{ env.FLAG == 'true' && github.ref == 'refs/heads/main' }}","handlingStrategy":"validation","validationCode":"// Keep a template-free pipeline: assert generated YAML contains no leftover '{{' or stray tokens before validation\nif strings.Contains(rendered, \"{{\") || strings.Count(expr, \"(\") != strings.Count(expr, \")\") {\n    return errors.New(\"possibly malformed expression in rendered workflow\")\n}","typeGuard":null,"tryCatchPattern":"Collect the joined parse errors, print all locations, fix the YAML; deterministic failure, no retry.","preventionTips":["Escape single quotes as '' inside single-quoted YAML scalars","Avoid nested templating engines that partially substitute ${{ }}","Run actionlint on every workflow edit"],"tags":["go","act","schema-validation","expressions","parse-error","yaml"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}