vitessio/vitess · error
reading JSON object key: %w
Error message
reading JSON object key: %w
What it means
This error wraps a failure that occurred while reading the string key of a JSON object during conversion of a raw JSON document into a MySQL SQL expression (JSON_OBJECT). The writeObject parser requires every object key to be a double-quoted JSON string, and writeStringContent (which reads and SQL-encodes that key) returned an error — e.g. the key string is unterminated, or contains a malformed escape sequence. The wrapper adds context so the caller knows the failure happened in the key portion of an object rather than in a value.
Source
Thrown at go/mysql/json/marshal.go:290
return nil
}
if !first {
if w.data[w.pos] != ',' {
return fmt.Errorf("expected ',' or '}' in object, got %q", w.data[w.pos])
}
w.pos++
w.buf.WriteString(", ")
w.skipWhitespace()
}
first = false
// Key (always a string).
if w.pos >= len(w.data) || w.data[w.pos] != '"' {
return errors.New("expected string key in JSON object")
}
w.buf.WriteString("_utf8mb4")
if err := w.writeStringContent(); err != nil {
return fmt.Errorf("reading JSON object key: %w", err)
}
w.buf.WriteString(", ")
// Colon separator.
w.skipWhitespace()
if w.pos >= len(w.data) || w.data[w.pos] != ':' {
return errors.New("expected ':' after object key")
}
w.pos++
// Value.
if err := w.writeValue(false, depth+1); err != nil {
return err
}
}
}
func (w *sqlWriter) writeArray(depth int) error {View on GitHub (pinned to 01a25a7d17)
Solutions
- Validate the JSON with encoding/json Unmarshal (or json.Valid) before passing it to the writer, so malformed keys are rejected with a standard parser error.
- Locate the object key at the reported position and fix or re-encode the JSON with a proper encoder (json.Marshal), which guarantees well-formed key strings and escapes.
- If input comes from an untrusted/external source, check for truncation (complete document received) and reject payloads that fail json.Valid with a clear client-side error.
- If the invalid escape comes from double-escaping (e.g. \"\\\\q\" produced by string escaping in another layer), remove the extra escaping layer in the producer.
Example fix
// before: hand-built JSON with invalid escape
payload := fmt.Sprintf(`{"na\\qme": %d}`, id)
// after: build JSON with the encoder
b, _ := json.Marshal(map[string]int{"name": id}) Defensive patterns
Strategy: validation
Validate before calling
if !json.Valid(input) {
return fmt.Errorf("invalid JSON document: object key not readable")
} Try / catch
if err := writeJSONAsSQL(input); err != nil {
var pe *json.SyntaxError
if errors.As(err, nil) || strings.Contains(err.Error(), "reading JSON object key") {
// fall back: reject or re-encode the document
return handleInvalidJSON(input, err)
}
return err
} Prevention
- Always produce JSON with json.Marshal/Encoder, never string concatenation
- Run json.Valid on untrusted input before conversion
- Guard against truncation: verify payload length/completeness before parsing
- Add a unit test with escaped characters in object keys
When it happens
Trigger: Calling the JSON-to-SQL writer (sqlWriter/writeValue path, e.g. via marshaling a JSON column value into JSON_OBJECT(...) SQL) with a document whose object key string is malformed: an unterminated key string (no closing quote before end of input), a key containing an invalid escape character (e.g. {"a\q": 1}), or a key with a truncated/invalid \u escape (e.g. {"\u12": 1}). Also triggered when the key string is truncated by a length-limited or corrupt input buffer.
Common situations: Applications storing hand-built JSON strings in a Vitess/MySQL JSON column where the JSON was assembled by string concatenation instead of a JSON encoder; corrupted JSON payloads arriving over the wire or read from a damaged binlog/audit log; truncation of a large JSON document by an intermediate layer (column size limits, log line cuts) leaving a key string open.
Related errors
- expected ',' or ']' in array, got %q
- invalid hex digit in \u escape: %q
- invalid escape character %q in JSON string
- invalid number at position %d in JSON
- overflow
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/dbae1c4d57e36e14.
Report an issue: GitHub.