antonmedv/fx · error
Expected colon after object key, got %q
Error message
Expected colon after object key, got %q
What it means
After scanning an object key string, the parser requires a ':' separating the key from its value. If the next non-whitespace character is not ':', it panics with this message showing the actual character found. This enforces the JSON object grammar key:value pair structure.
Source
Thrown at internal/jsonx/json.go:345
if p.char == '}' {
object.Value = curlyBracketPair
p.next()
return object
}
for {
// Expecting a key which should be a string
if p.char != '"' {
panic(fmt.Sprintf("Expected object key to be a string, got %q", p.char))
}
keyBytes := p.scanString()
p.skipWhitespace()
// Expecting colon after key
if p.char != ':' {
panic(fmt.Sprintf("Expected colon after object key, got %q", p.char))
}
p.next()
p.depth++
value := p.parseValue(false)
value.Key = keyBytes
value.Parent = object
p.depth--
object.Append(value)
object.Size += 1
p.skipWhitespace()
commaPos := p.end
if p.char == ',' {
object.End.Comma = trueView on GitHub (pinned to 4f31cd3a0c)
Solutions
- Insert the missing colon: {"a" 1} -> {"a": 1}
- Remove the extra key if the value was accidentally deleted ({"a"} -> {} or {"a": null})
- Check for wrong separator characters like ';' or '=' and replace with ':'
- Run the input through a JSON validator to locate the exact position
Example fix
// before
{"name": "x", "enabled" true}
// after
{"name": "x", "enabled": true} Defensive patterns
Strategy: validation
Validate before calling
func validateColonSeparators(src string) error {
// ensure every top-level key string inside an object is followed by ':'
depth := 0; inStr := false; expectColon := false
for i := 0; i < len(src); i++ {
c := src[i]
if inStr { if c == '\\' { i++ } else if c == '"' { inStr = false; if depth > 0 { expectColon = true } }; continue }
switch c {
case '"': inStr = true
case '{': depth++
case '}': depth--
case ':': expectColon = false
case ',', '{': if expectColon { return fmt.Errorf("missing ':' at offset %d", i) }
}
if expectColon && c != ':' && c != ' ' && c != '\t' && c != '\n' && c != '\r' {
return fmt.Errorf("expected ':' at offset %d, got %q", i, c)
}
}
return nil
} Try / catch
func safeParse(p *jsonx.JsonParser, data []byte) (root *jsonx.Node, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("json parse failed (missing colon?): %v", r)
}
}()
root = p.Parse(data)
return
} Prevention
- Use a serializer for generating JSON; never build objects with sprintf
- Lint JSON configs in CI before they reach runtime
- Check for regional keyboard mistakes (':' vs ';') in hand-edited files
- When truncating JSON streams, re-validate the remainder before parsing
When it happens
Trigger: Parsing {"a" 1} (colon omitted), {"a"; 1}, {"a" "b"}, or key followed immediately by '}' e.g. {"a"}.
Common situations: Typo'd separators in hand-edited JSON; JSON written from another language's map/string syntax; regex-generated JSON with wrong join characters; truncation cutting off the ':value' part.
Related errors
- Expected object key to be a string, got %q
- Unexpected character %q in object
- Invalid character %q in array
- Invalid escape sequence '\%c'
- Invalid character %q in number
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/c8ce3653dd618957.
Report an issue: GitHub.