{"record":{"id":"4e8d97951b665333","repo":"Tencent/APIJSON","slug":"1","errorCode":null,"errorMessage":"{}/{}:{} 的深度(或者说层级) 为 {} 已超限，必须在 1-{} 内 !","messagePattern":"(.+?)/(.+?):(.+?) 的深度\\(或者说层级\\) 为 (.+?) 已超限，必须在 1-(.+?) 内 !","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractParser.java","lineNumber":1169,"sourceCode":"\t\tif (Log.DEBUG) {\n\t\t\tLog.i(TAG, \"\\ngetObject:  parentPath = \" + parentPath\n\t\t\t\t\t+ \";\\n name = \" + name + \"; request = \" + JSON.toJSONString(request));\n\t\t}\n\t\tif (request == null) {// Moment:{}   || request.isEmpty()) {//key-value条件\n\t\t\treturn null;\n\t\t}\n\n\t\tint type = arrayConfig == null ? 0 : arrayConfig.getType();\n\t\tint position = arrayConfig == null ? 0 : arrayConfig.getPosition();\n\n\t\tString[] arr = StringUtil.split(parentPath, \"/\");\n\t\tif (position == 0) {\n\t\t\tint d = arr == null ? 1 : arr.length + 1;\n\t\t\tif (queryDepth < d) {\n\t\t\t\tqueryDepth = d;\n\t\t\t\tint maxQueryDepth = getMaxQueryDepth();\n\t\t\t\tif (queryDepth > maxQueryDepth) {\n\t\t\t\t\tthrow new IllegalArgumentException(parentPath + \"/\" + name + \":{} 的深度(或者说层级) 为 \" + queryDepth + \" 已超限，必须在 1-\" + maxQueryDepth + \" 内 !\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tapijson.orm.Entry<String, String> entry = Pair.parseEntry(name, true);\n\t\tString table = entry.getKey(); //Comment\n\t\t// String alias = entry.getValue(); //to\n\n\t\tboolean isTable = isTableKey(table);\n\t\tboolean isArrayMainTable = isSubquery == false && isTable && type == SQLConfig.TYPE_ITEM_CHILD_0 && arrayConfig != null && RequestMethod.isGetMethod(arrayConfig.getMethod(), true);\n\t\tboolean isReuse = isArrayMainTable && position > 0;\n\n\t\tObjectParser<T, M, L> op = null;\n\t\tif (isReuse) {  // 数组主表使用专门的缓存数据\n\t\t\top = arrayObjectParserCacheMap.get(parentPath.substring(0, parentPath.lastIndexOf(\"[]\") + 2));\n\t\t\top.setParentPath(parentPath);\n\t\t}\n","sourceCodeStart":1151,"sourceCodeEnd":1187,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java#L1151-L1187","documentation":"onObjectParse tracks the deepest response path (parentPath segments + 1). When position==0 (a new main-array item level) and the accumulated queryDepth exceeds getMaxQueryDepth(), IllegalArgumentException is thrown listing the path and the allowed 1..max range. It is a resource guard preventing exponential nested queries.","triggerScenarios":"Nesting arrays/objects deeper than the configured limit, e.g. [] -> 0:{} -> Comment[] -> 0:{} -> Comment:{} ... beyond maxQueryDepth (default 5). Each new level of a page-array item at position 0 increments the counter.","commonSituations":"Client builds recursive self-referencing structures (Comment -> reply User[] -> Moment[] -> Comment[]...); migrating from a version with a higher default depth; lowering maxQueryDepth in production for DoS protection and breaking existing deep queries; @combine of deep subqueries.","solutions":["Reduce nesting: split the deep query into several shallower requests and join client-side by id","Use引用赋值 (reference assignment, key@) to reuse sibling objects instead of re-querying deeper","Raise getMaxQueryDepth() server-side (override in your Parser subclass) if the depth is legitimate — weigh the DoS risk","Prefer POST S single-table queries for the deepest data instead of one monolithic tree"],"exampleFix":"// before (depth 6+)\n{\"[]\":{\"Comment[]\":{\"0\":{\"User\":{\"Moment\":{\"Comment[]\":{...}}}}}}}\n// after: two requests\n{\"Comment[]\":{\"@column\":\"id,userId\",\"@order\":\"id-\"}}\nthen {\"User\":{\"id{}@\":\"/Comment[]/userId\"}}","handlingStrategy":"validation","validationCode":"int depth = countNesting(requestJson); // walk [] and object children\nif (depth > MAX_QUERY_DEPTH) throw new IllegalStateException(\"query too deep: \" + depth);","typeGuard":"boolean withinQueryDepth(JsonNode n, int max) {\n  return measureDepth(n) <= max;\n}","tryCatchPattern":"catch (IllegalArgumentException e) { if (e.getMessage().contains(\"已超限\")) { splitQuery(e.getMessage()); } else throw e; }","preventionTips":["Split deep trees into multiple flat requests joined by id@","Cache the configured getMaxQueryDepth() client-side and assert against it","Prefer keyset pagination over deep nesting for graphs"],"tags":["apijson","depth-limit","nested-query","resource-guard"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}