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 = true

View on GitHub (pinned to 4f31cd3a0c)

Solutions

  1. Insert the missing colon: {"a" 1} -> {"a": 1}
  2. Remove the extra key if the value was accidentally deleted ({"a"} -> {} or {"a": null})
  3. Check for wrong separator characters like ';' or '=' and replace with ':'
  4. 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

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


AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02). Data as JSON: /api/errors/c8ce3653dd618957. Report an issue: GitHub.