{"record":{"id":"6e67f0adbfaa1a63","repo":"vitessio/vitess","slug":"too-big-depth-for-the-nested-json-it-exceeds-d","errorCode":null,"errorMessage":"too big depth for the nested JSON; it exceeds %d","messagePattern":"too big depth for the nested JSON; it exceeds (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mysql/json/marshal.go","lineNumber":234,"sourceCode":"\tpos     int\n\tbuf     *bytes2.Buffer\n\tscratch []byte\n}\n\nfunc (w *sqlWriter) skipWhitespace() {\n\tfor w.pos < len(w.data) {\n\t\tswitch w.data[w.pos] {\n\t\tcase ' ', '\\t', '\\n', '\\r':\n\t\t\tw.pos++\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (w *sqlWriter) writeValue(top bool, depth int) error {\n\tif depth >= MaxDepth {\n\t\treturn fmt.Errorf(\"too big depth for the nested JSON; it exceeds %d\", MaxDepth)\n\t}\n\tw.skipWhitespace()\n\tif w.pos >= len(w.data) {\n\t\treturn errors.New(\"unexpected end of JSON input\")\n\t}\n\tswitch w.data[w.pos] {\n\tcase '{':\n\t\tw.pos++\n\t\treturn w.writeObject(depth)\n\tcase '[':\n\t\tw.pos++\n\t\treturn w.writeArray(depth)\n\tcase '\"':\n\t\treturn w.writeString(top)\n\tcase 't', 'f':\n\t\treturn w.writeBool(top)\n\tcase 'n':\n\t\treturn w.writeNull(top)","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mysql/json/marshal.go#L216-L252","documentation":"When converting JSON text to Vitess SQL (AppendMarshalSQL path), sqlWriter.writeValue enforces a maximum nesting depth (MaxDepth). If the input JSON nests deeper than that limit, the writer aborts with this error instead of recursing unboundedly, protecting against stack exhaustion. The depth counter increments as writeValue, writeObject, and writeArray recurse into each other.","triggerScenarios":"Calling AppendMarshalSQL (or the internal writeValue/writeObject/writeArray recursion) on JSON input containing more than MaxDepth levels of nested objects/arrays, e.g. a deeply nested '[[[[[...]]]]]' payload from an untrusted source.","commonSituations":"Malicious or auto-generated deeply nested JSON in a SQL payload; client libraries serializing recursive data structures; fuzzing or adversarial input; accidental runaway nesting from a buggy serializer upstream.","solutions":["Reduce the nesting depth of the JSON input before marshaling (flatten or cap nesting at MaxDepth levels)","Validate/limit nesting depth on input at the application boundary before passing it to AppendMarshalSQL","If legitimate data requires deeper nesting, raise MaxDepth in go/mysql/json (accepting the larger recursion/stack cost)","Reject the offending document and return a clear error to the client rather than attempting conversion"],"exampleFix":"// before\npayload := strings.Repeat(\"[\", 200) + strings.Repeat(\"]\", 200)\nout, err := json.AppendMarshalSQL(nil, []byte(payload))\n// after\npayload := limitNestingDepth(payload, json.MaxDepth)\nout, err := json.AppendMarshalSQL(nil, []byte(payload))","handlingStrategy":"validation","validationCode":"func depthLimited(data []byte, max int) bool {\n    depth, stack := 0, []rune{}\n    inStr := false\n    for _, r := range string(data) {\n        if inStr { if r == '\\\\' { continue }; if r == '\"' { inStr = false }; continue }\n        switch r {\n        case '\"': inStr = true\n        case '{', '[': stack = append(stack, r); depth = max(depth, len(stack))\n        case '}', ']': stack = stack[:len(stack)-1]\n        }\n    }\n    return depth <= max\n}\nif !depthLimited(raw, json.MaxDepth) { return errors.New(\"input exceeds max JSON nesting depth\") }","typeGuard":null,"tryCatchPattern":"out, err := json.AppendMarshalSQL(nil, raw)\nif err != nil {\n    if strings.Contains(err.Error(), \"too big depth\") {\n        return fmt.Errorf(\"rejecting document exceeding JSON depth limit: %w\", err)\n    }\n    return err\n}","preventionTips":["Cap nesting depth at the ingestion boundary before untrusted JSON enters the system","Flatten deeply nested structures before converting to SQL","Keep the depth-check helper in sync with the library's MaxDepth constant","Treat excessive-depth payloads as hostile input and reject with a 4xx-style error"],"tags":["go","json","recursion","depth-limit","security"],"backgroundTag":"max-nesting-depth-exceeded","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}