{"record":{"id":"d1a79dca0c85aa68","repo":"nektos/act","slug":"missing-parameters-for-s-expected-v-got-v","errorCode":null,"errorMessage":"Missing parameters for %s expected >= %v got %v","messagePattern":"Missing parameters for (.+?) expected >= (.+?) got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/schema/schema.go","lineNumber":145,"sourceCode":"\t\tswitch exprNode.Token().Kind {\n\t\tcase actionlint.TokenKindInt:\n\t\tcase actionlint.TokenKindFloat:\n\t\tcase actionlint.TokenKindString:\n\t\t\treturn nil\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"expressions are not allowed here\")\n\t\t}\n\t}\n\n\tfuncs := s.GetFunctions()\n\n\tvar err error\n\tactionlint.VisitExprNode(exprNode, func(node, _ actionlint.ExprNode, entering bool) {\n\t\tif funcCallNode, ok := node.(*actionlint.FuncCallNode); entering && ok {\n\t\t\tfor _, v := range *funcs {\n\t\t\t\tif strings.EqualFold(funcCallNode.Callee, v.name) {\n\t\t\t\t\tif v.min > len(funcCallNode.Args) {\n\t\t\t\t\t\terr = errors.Join(err, fmt.Errorf(\"Missing parameters for %s expected >= %v got %v\", funcCallNode.Callee, v.min, len(funcCallNode.Args)))\n\t\t\t\t\t}\n\t\t\t\t\tif v.max < len(funcCallNode.Args) {\n\t\t\t\t\t\terr = errors.Join(err, fmt.Errorf(\"Too many parameters for %s expected <= %v got %v\", funcCallNode.Callee, v.max, len(funcCallNode.Args)))\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = errors.Join(err, fmt.Errorf(\"Unknown Function Call %s\", funcCallNode.Callee))\n\t\t}\n\t\tif varNode, ok := node.(*actionlint.VariableNode); entering && ok {\n\t\t\tfor _, v := range s.Context {\n\t\t\t\tif strings.EqualFold(varNode.Name, v) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = errors.Join(err, fmt.Errorf(\"Unknown Variable Access %s\", varNode.Name))\n\t\t}\n\t})","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/schema/schema.go#L127-L163","documentation":"Validation error from checkSingleExpression in pkg/schema/schema.go when a function call inside a ${{ }} expression has fewer arguments than the function's declared minimum arity (from the GetFunctions table, e.g. contains/endsWith/startsWith need exactly 2, format needs >=1).","triggerScenarios":"Calling a known expression function with too few args: ${{ contains() }}, ${{ startsWith(github.ref) }}, ${{ join() }}. The check compares v.min > len(funcCallNode.Args) using actionlint's parsed AST.","commonSituations":"Typos or copy-paste mistakes in workflow expressions; writing expressions against GitHub docs but forgetting an argument; refactoring an expression and dropping a parameter.","solutions":["Add the missing argument(s) — check the arity table in schema.go GetFunctions (contains/endsWith/startsWith: 2, format: >=1, join: 1-2)","Validate the workflow with actionlint or `act` schema validation before committing","Test the expression in a scratch workflow step to confirm it evaluates"],"exampleFix":"# before:\nif: ${{ startsWith(github.ref) }}\n# after:\nif: ${{ startsWith(github.ref, 'refs/tags/') }}","handlingStrategy":"validation","validationCode":"// Verify arity against act's table before shipping the workflow:\nvar arity = map[string][2]int{\"contains\": {2, 2}, \"endsWith\": {2, 2}, \"format\": {1, 255}, \"join\": {1, 2}, \"startsWith\": {2, 2}}\n// ensure len(args) is within [min, max] for every call you write","typeGuard":null,"tryCatchPattern":"Fail validation with the message included; no retry. Fix the expression and re-validate.","preventionTips":["Copy function signatures from the GitHub expressions docs","Run actionlint locally — it catches arity errors at lint time","Add a CI step that lints all workflows in .github/workflows"],"tags":["go","act","schema-validation","expressions","function-arity"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}