anomalyco/sst · error
expect JSON object close with '}'
Error message
expect JSON object close with '}'
What it means
After consuming all key/value pairs, UnmarshalJSON reads the closing token and requires it to be the '}' delimiter. Getting anything else means the object was truncated, an array was supplied, or trailing content is structurally invalid.
Source
Thrown at internal/util/kv.go:54
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 {
return err
}
t, err = dec.Token()
if err != io.EOF {
return fmt.Errorf("expect end of JSON object but got more token: %T: %v or err: %v", t, t, err)
}
return nil
}
func (p KeyValuePairs[T]) MarshalJSON() ([]byte, error) {
buf := &bytes.Buffer{}
buf.Write([]byte{'{'})
for i, KeyValuePair := range p {
buf.WriteString(fmt.Sprintf("%q:", fmt.Sprintf("%v", KeyValuePair.Key)))View on GitHub (pinned to a0bd20f762)
Solutions
- Check that the full payload arrives intact — log the raw body and verify it ends with '}'
- Fix Content-Length/chunked issues (timeouts, proxies) causing truncation
- Ensure the top-level structure is an object, not an array
Example fix
// before
data := readPartial(resp.Body) // truncated stream
json.Unmarshal(data, &kv) // expect JSON object close with '}'
// after
var buf bytes.Buffer
_, err := io.Copy(&buf, resp.Body)
if err != nil { return err } // surface read errors instead
json.Unmarshal(buf.Bytes(), &kv) Defensive patterns
Strategy: validation
Validate before calling
if !json.Valid(raw) {
return fmt.Errorf("payload is not valid/truncated JSON")
}
trimmed := bytes.TrimSpace(raw)
if len(trimmed) > 0 && trimmed[len(trimmed)-1] != '}' {
return fmt.Errorf("payload does not end with '}'")
} Try / catch
var kv KeyValuePairs[string]
if err := json.Unmarshal(raw, &kv); err != nil {
if strings.Contains(err.Error(), "expect JSON object close") {
return fmt.Errorf("truncated response; check body transfer: %w", err)
}
return err
} Prevention
- Always read the HTTP body to completion (io.Copy) before decoding
- Check Content-Length vs received bytes on large payloads
- Increase proxy/read timeouts to avoid mid-body truncation
When it happens
Trigger: Truncated JSON body (network cut mid-response) so the decoder hits EOF where '}' was expected; decoding a JSON array; interleaved/broken streaming input.
Common situations: HTTP response body cut off by proxy timeouts; partial file reads; payload wrapped in an array at the top level after a producer refactor.
Related errors
- expect JSON object open with '{'
- expecting JSON key should be always a string: %T: %v
- JSON value can't be decoded: %T: %v
- 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/84cb244596c3f504.
Report an issue: GitHub.