nektos/act · error

Unclosed brackets. The following format string is invalid: '

Error message

Unclosed brackets. The following format string is invalid: '%s'

What it means

Thrown by format() when the input ends while still inside a placeholder: an opening '{' was consumed (state bracketOpen) but no closing '}' arrived. The string is truncated after an unescaped brace.

Source

Thrown at pkg/exprparser/functions.go:130

			}

		case bracketClose: // found }
			switch character {
			case '}':
				output += "}"
				replacementIndex = ""
				state = passThrough

			default:
				panic("Invalid format parser state")
			}
		}
	}

	if state != passThrough {
		switch state {
		case bracketOpen:
			return "", fmt.Errorf("Unclosed brackets. The following format string is invalid: '%s'", input)

		case bracketClose:
			return "", fmt.Errorf("Closing bracket without opening one. The following format string is invalid: '%s'", input)
		}
	}

	return output, nil
}

func (impl *interperterImpl) join(array reflect.Value, sep reflect.Value) (string, error) {
	separator := impl.coerceToString(sep).String()
	switch array.Kind() {
	case reflect.Slice:
		var items []string
		for i := 0; i < array.Len(); i++ {
			items = append(items, impl.coerceToString(array.Index(i).Elem()).String())
		}

View on GitHub (pinned to 4f41128141)

Solutions

  1. Close every placeholder: format('Hello {0').
  2. Escape literal braces with double braces '{{' '}}'.
  3. Prefer string concatenation or toJSON for brace-heavy output instead of format().

Example fix

# before
${{ format('value = {0', x) }}
# after
${{ format('value = {0}', x) }}
Defensive patterns

Strategy: validation

Validate before calling

func balancedBraces(tpl string) bool {
  depth := 0
  for i := 0; i < len(tpl); i++ {
    if tpl[i] == '{' && i+1 < len(tpl) && tpl[i+1] == '{' { i++; continue }
    if tpl[i] == '}' && i+1 < len(tpl) && tpl[i+1] == '}' { i++; continue }
    switch tpl[i] {
    case '{': depth++
    case '}': depth--
    }
    if depth < 0 || depth > 1 { return false }
  }
  return depth == 0
}

Prevention

When it happens

Trigger: format('Hello {0') — missing closing brace; odd number of braces like format('{'); a brace intended literally that was not escaped as '{{'.

Common situations: Hand-editing long format strings; templates whose content contains JSON or CSS braces; typos when escaping braces (single '{' instead of '{{').

Related errors


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/8a9c2beefafd0d4c. Report an issue: GitHub.