alibaba/spring-ai-alibaba · error · IllegalArgumentException

序列化 supportedParameters 失败

Error message

序列化 supportedParameters 失败

What it means

toEntity serializes m.supportedParameters to a JSON string using a fresh ObjectMapper; any writeValueAsString failure is wrapped in this IllegalArgumentException with the original exception as cause. Like defaultParameters, this field comes from user YAML and must be JSON-serializable to be stored in the entity.

Source

Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/repository/impl/FileModelConfigRepository.java:159

    
    private ModelConfigDO toEntity(YamlModel m) {
        ModelConfigDO.ModelConfigDOBuilder b = ModelConfigDO.builder().id(m.id).name(m.name)
                .provider(m.provider.toLowerCase()).modelName(m.modelName).baseUrl(m.baseUrl)
                .apiKey(environment != null ? environment.resolvePlaceholders(m.apiKey) : m.apiKey).status(m.status)
                .createTime(LocalDateTime.now()).updateTime(LocalDateTime.now());
        
        if (m.defaultParameters != null) {
            try {
                b.defaultParameters(new ObjectMapper().writeValueAsString(m.defaultParameters));
            } catch (Exception e) {
                throw new IllegalArgumentException("序列化 defaultParameters 失败", e);
            }
        }
        if (m.supportedParameters != null) {
            try {
                b.supportedParameters(new ObjectMapper().writeValueAsString(m.supportedParameters));
            } catch (Exception e) {
                throw new IllegalArgumentException("序列化 supportedParameters 失败", e);
            }
        }
        return b.build();
    }
    
    private void startWatchService() {
        try {
            Path dir = this.configPath.getParent();
            if (dir == null) {
                return;
            }
            WatchService ws = FileSystems.getDefault().newWatchService();
            dir.register(ws, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
            ExecutorService executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "model-config-watch"));
            executor.submit(() -> {
                log.info("开始监听模型配置文件变更: {}", configPath);
                while (true) {
                    WatchKey key = ws.take();

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Read the wrapped cause to see the exact Jackson error (e.g., 'Direct self-reference leading to cycle')
  2. Rewrite supportedParameters in the YAML as plain JSON-compatible structures (strings, numbers, lists, maps)
  3. Eliminate recursive anchors/aliases or convert them to explicit inline values
  4. Provide a custom serializer or ObjectMapper configuration if complex types must be supported

Example fix

// before (models.yml)
supportedParameters: &params
  - temperature
  nested: *params   # cyclic reference
// after
supportedParameters:
  - temperature
  - top_p
  - max_tokens
Defensive patterns

Strategy: validation

Validate before calling

// Java: ensure supportedParameters is JSON-serializable before assignment
new ObjectMapper().writeValueAsString(model.getSupportedParameters()); // throws early if not

Type guard

boolean isJsonSafe(Object v) {
    try { new ObjectMapper().writeValueAsString(v); return true; }
    catch (JsonProcessingException e) { return false; }
}

Try / catch

try {
    entity = toEntity(model);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("supportedParameters")) {
        log.error("supportedParameters is not JSON-serializable", e.getCause());
    }
}

Prevention

When it happens

Trigger: Calling toEntity (via entity()) on a model whose supportedParameters contains values Jackson cannot serialize (cyclic references, non-bean types).

Common situations: Anchors/aliases in YAML expanding to recursive structures; storing unusual value types (e.g., nested custom objects) in supportedParameters; refactoring the config class to hold richer objects without updating serialization.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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