alibaba/spring-ai-alibaba · error · YAMLException

Schema extensions recursion depth limit(%d) reached.

Error message

Schema extensions recursion depth limit(%d) reached.

What it means

checkSchemaExtension() recursively expands OpenAPI schema extensions ($ref-style defined extension) while building output parameters; to prevent runaway recursion from circular schema references it enforces MAX_DEPTH and throws YAMLException when the depth limit is reached.

Source

Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/utils/api/OpenApiUtils.java:594

								result, 0));
				}
			});
		}
		return result;
	}

	/**
	 * Checks schema extensions
	 * @param schemaField Schema field name
	 * @param schema Schema object
	 * @param resultList List to store results
	 * @param currentDepth Current recursion depth
	 * @throws YAMLException If recursion depth limit is reached
	 */
	private static void checkSchemaExtension(String schemaField, Schema<?> schema, List<ApiParameter> resultList,
			int currentDepth) throws YAMLException {
		if (currentDepth >= MAX_DEPTH) {
			throw new YAMLException(String.format("Schema extensions recursion depth limit(%d) reached.", MAX_DEPTH));
		}

		if (!CollectionUtils.isEmpty(schema.getExtensions())) {
			Object paramSource = schema.getExtensions().get(DEFINED_EXTENSION);
			if (paramSource instanceof String && String.valueOf(paramSource).equals(EXTENSION_USER_SOURCE)) {
				String type = schema.getType();
				// 防止用户使用 "token" 类型的参数
				if (StringUtils.isNotBlank(type) && TOKEN_TYPE.equals(type)) {
					throw new YAMLException("Type \"token\" is not allowed.");
				}

				ApiParameter param = new ApiParameter();
				param.setKey(schemaField);
				param.setType(type);
				param.setDescription(schema.getDescription());
				resultList.add(param);
			}
		}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Break the circular reference in the OpenAPI spec — inline one level or split the recursive model into shallower objects
  2. Flatten deeply nested response models into fewer levels before importing
  3. Increase MAX_DEPTH in OpenApiUtils if legitimately deep schemas must be supported (watch memory/stack)

Example fix

// before: Node -> children -> Node (circular)
// after
Node:
  type: object
  properties:
    children:
      type: array
      items:
        type: object
        properties:
          id: {type: string}
Defensive patterns

Strategy: validation

Validate before calling

// detect circular schema extension references before import
Set<String> visited = new HashSet<>();
Deque<Schema<?>> stack = new ArrayDeque<>(List.of(rootSchema));
while (!stack.isEmpty()) {
    Schema<?> s = stack.pop();
    if (!visited.add(System.identityHashCode(s) + ":" + s.getType())) {
        throw new IllegalArgumentException("Circular schema extension detected");
    }
    if (s.getProperties() != null) stack.addAll(s.getProperties().values());
}

Try / catch

try {
    OpenApiUtils.parseSchemaToForm(spec);
} catch (YAMLException e) {
    if (e.getMessage().contains("recursion depth limit")) {
        // locate the circular/nested model and flatten it before re-import
    }
}

Prevention

When it happens

Trigger: Importing an OpenAPI spec whose schema extensions reference each other cyclically (A -> B -> A) or nest beyond MAX_DEPTH levels, during parseRestfulMethod output-parameter extraction.

Common situations: Recursive/circular models in specs (tree nodes, linked lists); deeply nested generated DTOs; specs where $ref-like extension chains were not resolved before import.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/218f6db03e84fe27. Report an issue: GitHub.