nektos/act · error
%sFailed to parse: %s
Error message
%sFailed to parse: %s
What it means
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.
Source
Thrown at pkg/schema/schema.go:218
}
func (s *Node) checkExpression(node *yaml.Node) (bool, error) {
val := node.Value
hadExpr := false
var err error
for {
if i := strings.Index(val, "${{"); i != -1 {
val = val[i+3:]
} else {
return hadExpr, err
}
hadExpr = true
parser := actionlint.NewExprParser()
lexer := actionlint.NewExprLexer(val)
exprNode, parseErr := parser.Parse(lexer)
if parseErr != nil {
err = errors.Join(err, fmt.Errorf("%sFailed to parse: %s", formatLocation(node), parseErr.Message))
continue
}
val = val[lexer.Offset():]
cerr := s.checkSingleExpression(exprNode)
if cerr != nil {
err = errors.Join(err, fmt.Errorf("%s%w", formatLocation(node), cerr))
}
}
}
func AddFunction(funcs *[]FunctionInfo, s string, i1, i2 int) {
*funcs = append(*funcs, FunctionInfo{
name: s,
min: i1,
max: i2,
})
}
View on GitHub (pinned to 4f41128141)
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
Example fix
# before:
if: ${{ env.FLAG == 'true' && (github.ref
# after:
if: ${{ env.FLAG == 'true' && github.ref == 'refs/heads/main' }} Defensive patterns
Strategy: validation
Validate before calling
// Keep a template-free pipeline: assert generated YAML contains no leftover '{{' or stray tokens before validation
if strings.Contains(rendered, "{{") || strings.Count(expr, "(") != strings.Count(expr, ")") {
return errors.New("possibly malformed expression in rendered workflow")
} Try / catch
Collect the joined parse errors, print all locations, fix the YAML; deterministic failure, no retry.
Prevention
- Escape single quotes as '' inside single-quoted YAML scalars
- Avoid nested templating engines that partially substitute ${{ }}
- Run actionlint on every workflow edit
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- expressions are not allowed here
- %sinsert is not allowed here
- Missing parameters for %s expected >= %v got %v
- Too many parameters for %s expected <= %v got %v
- Unknown Function Call %s
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/c9343bd80a1f0be6.
Report an issue: GitHub.