anomalyco/sst · error
expecting JSON key should be always a string: %T: %v
Error message
expecting JSON key should be always a string: %T: %v
What it means
While iterating the object's key tokens, UnmarshalJSON requires every key to be a JSON string. JSON technically allows only string keys, but raw/duplicate decoding or malformed input can surface a non-string token, producing this typed error with the offending Go type and value.
Source
Thrown at internal/util/kv.go:38
// must open with a delim token '{'
t, err := dec.Token()
if err != nil {
return err
}
if delim, ok := t.(json.Delim); !ok || delim != '{' {
return fmt.Errorf("expect JSON object open with '{'")
}
for dec.More() {
t, err = dec.Token()
if err != nil {
return err
}
key, ok := t.(string)
if !ok {
return fmt.Errorf("expecting JSON key should be always a string: %T: %v", t, t)
}
var value T
err = dec.Decode(&value)
if err != nil {
return fmt.Errorf("JSON value can't be decoded: %T: %v", value, value)
}
*p = append(*p, KeyValuePair[T]{Key: key, Value: value})
}
// must end with a delim token '}'
t, err = dec.Token()
if err != nil {
return err
}
if delim, ok := t.(json.Delim); !ok || delim != '}' {
return fmt.Errorf("expect JSON object close with '}'")
}
if err != nil {View on GitHub (pinned to a0bd20f762)
Solutions
- Fix the producer to emit RFC-8259 JSON with quoted string keys
- Run the payload through a strict JSON validator to find the malformed key
- If keys are numeric upstream, stringify them before serialization
Example fix
// before
{"123": "v"} // generated as {123: "v"} by a JS template
// after
JSON.stringify(obj) // yields {"123":"v"} with quoted keys Defensive patterns
Strategy: validation
Validate before calling
var probe map[string]json.RawMessage
if err := json.Unmarshal(raw, &probe); err != nil {
return fmt.Errorf("not an object with string keys: %w", err)
} Type guard
func hasStringKeys(raw []byte) bool {
var m map[string]json.RawMessage
return json.Unmarshal(raw, &m) == nil
} Try / catch
var kv KeyValuePairs[string]
if err := json.Unmarshal(raw, &kv); err != nil {
if strings.Contains(err.Error(), "key should be always a string") {
return fmt.Errorf("malformed JSON key in payload: %w", err)
}
return err
} Prevention
- Never hand-build JSON with string templates; use a serializer
- Reject non-standard JSON (JSON5/HJSON) at the boundary
- Fuzz/validate inputs in tests with malformed key cases
When it happens
Trigger: Input containing a non-string key token — practically seen when decoding malformed/NDJSON-like input into KeyValuePairs, e.g. '{1:"x"}' produced by a hand-built JSON string.
Common situations: Hand-rolled JSON generation in another language (JS object with numeric keys serialized oddly, or template-built JSON); a middleware or proxy mangling payloads; unquoted keys from lenient serializers (JSON5/HJSON).
Related errors
- expect JSON object open with '{'
- JSON value can't be decoded: %T: %v
- expect JSON object close with '}'
- expect end of JSON object but got more token: %T: %v or err:
- panic(err)
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/21353e73912a2b5a.
Report an issue: GitHub.