{"record":{"id":"b81cda01d177e15a","repo":"alibaba/spring-ai-alibaba","slug":"config-is-null","errorCode":null,"errorMessage":"config is null","messagePattern":"config is null","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/builder/generator/service/dsl/adapters/StudioDSLAdapter.java","lineNumber":314,"sourceCode":"\tpublic ChatBot mapToChatBot(Map<String, Object> data) {\n\t\tthrow new UnsupportedOperationException();\n\t}\n\n\t@Override\n\tpublic Map<String, Object> chatbotToMap(ChatBot chatBot) {\n\t\tthrow new UnsupportedOperationException();\n\t}\n\n\t@Override\n\tpublic void validateDSLData(Map<String, Object> data) {\n\t\tString type = MapReadUtil.getMapDeepValue(data, String.class, \"type\");\n\t\tif (!\"workflow\".equalsIgnoreCase(type)) {\n\t\t\tthrow new UnsupportedOperationException(\"Unsupported type: \" + type);\n\t\t}\n\n\t\tMap<?, ?> config = MapReadUtil.getMapDeepValue(data, Map.class, \"config\");\n\t\tif (config == null) {\n\t\t\tthrow new IllegalArgumentException(\"config is null\");\n\t\t}\n\n\t\t// 检查config是否为WorkflowConfig\n\t\ttry {\n\t\t\tOBJECT_MAPPER.convertValue(config, WorkflowConfig.class);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new IllegalArgumentException(\"Invalid config!\");\n\t\t}\n\t}\n\n\t@Override\n\tpublic Serializer getSerializer() {\n\t\treturn this.serializer;\n\t}\n\n\t@Override\n\tpublic Boolean supportDialect(DSLDialectType dialectType) {","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/builder/generator/service/dsl/adapters/StudioDSLAdapter.java#L296-L332","documentation":"Thrown by StudioDSLAdapter.validateDSLData as IllegalArgumentException when the 'config' object is absent from the workflow DSL. After checking type=='workflow', the adapter deep-reads 'config' and requires it to exist because it holds the entire workflow definition (nodes, edges, metadata).","triggerScenarios":"Importing a Studio workflow DSL that contains type but no 'config' key; config nested at a different path than the deep lookup expects; config explicitly set to null; partial DSL assembled programmatically without the config block.","commonSituations":"Hand-trimmed export files; preprocessed DSL where config was moved or renamed; writing DSL maps in code and forgetting the config payload; export interrupted/corrupted so config was dropped.","solutions":["Add the 'config' object containing the workflow definition to the DSL map","Re-export the workflow from Studio to get a complete document","Verify the config key path matches what MapReadUtil.getMapDeepValue(data, Map.class, \"config\") expects","Validate the JSON structure of your export against a known-good Studio workflow DSL"],"exampleFix":"// before\n{\"type\": \"workflow\"}\n\n// after\n{\"type\": \"workflow\", \"config\": {\"nodes\": [...], \"edges\": [...]}}","handlingStrategy":"validation","validationCode":"if (dslData.get(\"config\") == null) {\n    throw new IllegalArgumentException(\"Studio workflow DSL requires a 'config' object\");\n}","typeGuard":"boolean hasConfig(Map<String,Object> dsl) { return dsl.get(\"config\") instanceof Map; }","tryCatchPattern":"try { studioAdapter.importDSL(data); } catch (IllegalArgumentException e) { if (\"config is null\".equals(e.getMessage())) { log.error(\"DSL dropped its 'config' block; re-export the workflow\"); } throw e; }","preventionTips":["Never strip the config block when trimming DSL files","Verify deep-lookup path for 'config' matches your document layout","Compare against a complete Studio export to confirm all top-level keys are present"],"tags":["studio","validation","missing-field"],"backgroundTag":"missing-required-config-field","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}