wavetermdev/waveterm · error
unmatched bracket at position %d
Error message
unmatched bracket at position %d
What it means
ParseSimplePath parses ijson path strings like 'a.b[0].c'. When it encounters '[', it searches for the closing ']' with strings.Index; if none exists anywhere in the remaining input, it returns 'unmatched bracket at position %d'. The path string is malformed and nothing is parsed.
Source
Thrown at pkg/ijson/ijson.go:70
func MakeAppendCommand(path Path, value any) Command {
return Command{
"type": AppendCommandStr,
"path": path,
"data": value,
}
}
var pathPartKeyRe = regexp.MustCompile(`^[a-zA-Z0-9:_#-]+`)
func ParseSimplePath(input string) ([]any, error) {
var path []any
// Scan the input string character by character
for i := 0; i < len(input); {
if input[i] == '[' {
// Handle the index
end := strings.Index(input[i:], "]")
if end == -1 {
return nil, fmt.Errorf("unmatched bracket at position %d", i)
}
index, err := strconv.Atoi(input[i+1 : i+end])
if err != nil {
return nil, fmt.Errorf("invalid index at position %d: %v", i, err)
}
path = append(path, index)
i += end + 1
} else {
// Handle the key
j := i
for j < len(input) && input[j] != '.' && input[j] != '[' {
j++
}
key := input[i:j]
if !pathPartKeyRe.MatchString(key) {
return nil, fmt.Errorf("invalid key at position %d: %s", i, key)
}
path = append(path, key)View on GitHub (pinned to a4447c1563)
Solutions
- Validate/complete the bracket syntax in the input string before calling ParseSimplePath.
- Reject the path at the input boundary and surface a user-facing message about unbalanced brackets.
- If paths come from templates, fix the template so index syntax is `key[<int>]`.
Example fix
// before
path, err := ijson.ParseSimplePath("window[0") // unmatched bracket at position 6
// after
func validateSimplePath(s string) error {
depth := 0
for _, r := range s {
if r == '[' { depth++ } else if r == ']' { depth--; if depth < 0 { return errors.New("extra ]") } }
}
if depth != 0 { return errors.New("unbalanced brackets") }
return nil
}
if err := validateSimplePath("window[0]"); err != nil { return err }
path, err := ijson.ParseSimplePath("window[0]") Defensive patterns
Strategy: validation
Validate before calling
func hasBalancedBrackets(s string) bool {
depth := 0
for _, r := range s {
if r == '[' { depth++ } else if r == ']' { depth--; if depth < 0 { return false } }
}
return depth == 0
}
if !hasBalancedBrackets(userPath) { return errors.New("unbalanced brackets in path") } Try / catch
path, err := ijson.ParseSimplePath(input)
if err != nil {
return fmt.Errorf("invalid path %q: %w", input, err) // surface position to user
} Prevention
- Validate path syntax at the input boundary with a regex like ^\w+(\.\w+|\[\d+\])*$ .
- Escape or reject user-supplied strings that may contain '[' before treating them as paths.
- Never build path strings by concatenation of untrusted fragments; use ijson.Path slices directly when the structure is known.
When it happens
Trigger: Calling ParseSimplePath (directly, or indirectly with a user-supplied path string) with input containing '[' but no subsequent ']' — e.g. "users[0" or "a[".
Common situations: Path strings typed by users in a UI/CLI and passed unvalidated; string interpolation that dropped the closing bracket; truncation of a path during logging or templating.
Related errors
- invalid index at position %d: %v
- invalid key at position %d: %s
- backup metadata mismatch: expected %s, got %s
- invalid format of user@host argument
- invalid object reference: %q
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/58bd581954d50bb5.
Report an issue: GitHub.