nektos/act · error
The following format string is invalid: '%s'
Error message
The following format string is invalid: '%s'
What it means
Thrown by the expression format() function when a {...} placeholder's index part cannot be parsed as an integer (strconv.ParseInt fails). GitHub's format() only supports {0}, {1}, ... placeholders, so '{foo}' or '{}' with empty accumulated index text yields this error.
Source
Thrown at pkg/exprparser/functions.go:97
case '}':
state = bracketClose
default:
output += string(character)
}
case bracketOpen: // found {
switch character {
case '{':
output += "{"
replacementIndex = ""
state = passThrough
case '}':
index, err := strconv.ParseInt(replacementIndex, 10, 32)
if err != nil {
return "", fmt.Errorf("The following format string is invalid: '%s'", input)
}
replacementIndex = ""
if len(replaceValue) <= int(index) {
return "", fmt.Errorf("The following format string references more arguments than were supplied: '%s'", input)
}
output += impl.coerceToString(replaceValue[index]).String()
state = passThrough
default:
replacementIndex += string(character)
}
case bracketClose: // found }
switch character {View on GitHub (pinned to 4f41128141)
Solutions
- Use positional placeholders: format('Hello {0}', name).
- Escape literal braces: '{{' and '}}' for literal { and } in the output.
- For JSON output prefer toJSON() instead of format().
- Check the workflow locally with actionlint, which flags malformed format strings.
Example fix
# before
run: echo ${{ format('Hi {name}', github.actor) }}
# after
run: echo ${{ format('Hi {0}', github.actor) }} Defensive patterns
Strategy: validation
Validate before calling
var ph = regexp.MustCompile(`\{([^}]*)\}`)
func validPlaceholders(s string) bool {
s = strings.ReplaceAll(s, '{{', '').ReplaceAll(s, '}}', '')
for _, m := range ph.FindAllStringSubmatch(s, -1) {
if _, err := strconv.Atoi(m[1]); err != nil { return false }
}
return true
} Try / catch
if _, err := parser.Format(tpl, args...); err != nil {
if strings.Contains(err.Error(), 'invalid') { tpl = sanitizePlaceholders(tpl) } else { return err }
} Prevention
- Use only integer placeholders {0},{1}...
- Escape literal braces as {{ }}
- Lint workflows with actionlint before committing
When it happens
Trigger: A workflow expression like format('Hello {name}', inputs.name) — literal braces must be escaped as '{{' and '}}'; format('{a}') with no valid integer; empty index '{}'.
Common situations: Trying to use Python/JS-style named placeholders in format(); writing JSON templates inside format() without doubling braces; migrating from other template engines.
Related errors
- The following format string references more arguments than w
- Unclosed brackets. The following format string is invalid: '
- Closing bracket without opening one. The following format st
- Cannot convert value to JSON. Cause: %v
- Cannot parse non-string type %v as JSON
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/74c9ad2fed5ffedc.
Report an issue: GitHub.