{"record":{"id":"704ee9e126f50360","repo":"alibaba/spring-ai-alibaba","slug":"template-string-is-null","errorCode":null,"errorMessage":"Template string is null","messagePattern":"Template string is null","errorType":"validation","errorClass":"NullPointerException","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/AbstractNodeDataConverter.java","lineNumber":88,"sourceCode":"\t * dialects.\n\t */\n\tpublic interface DialectConverter<T> {\n\n\t\tBoolean supportDialect(DSLDialectType dialectType);\n\n\t\tT parse(Map<String, Object> data) throws JsonProcessingException;\n\n\t\tMap<String, Object> dump(T nodeData);\n\n\t\t/**\n\t\t * 将模板字符串转换为变量选择器\n\t\t * @param dialectType dsl语言\n\t\t * @param template 模板字符串\n\t\t * @return 变量选择器\n\t\t */\n\t\tdefault VariableSelector varTemplateToSelector(DSLDialectType dialectType, String template) {\n\t\t\tif (template == null) {\n\t\t\t\tthrow new NullPointerException(\"Template string is null\");\n\t\t\t}\n\t\t\tPattern pattern = switch (dialectType) {\n\t\t\t\tcase DIFY -> DIFY_VAR_TEMPLATE_PATTERN;\n\t\t\t\tcase STUDIO -> STUDIO_VAR_TEMPLATE_PATTERN;\n\t\t\t\tdefault -> throw new UnsupportedOperationException();\n\t\t\t};\n\t\t\tMatcher matcher = pattern.matcher(template);\n\t\t\tMatchResult result = matcher.results()\n\t\t\t\t.findFirst()\n\t\t\t\t.orElseThrow(() -> new IllegalArgumentException(\"Invalid template string\"));\n\t\t\treturn new VariableSelector(result.group(1), result.group(2));\n\t\t}\n\n\t\t/**\n\t\t * 从data中获取模型名称（LLMNode、ClassifierNode等共同使用）\n\t\t * @param dialectType dsl语言\n\t\t * @param data 节点数据\n\t\t * @return 模型名称","sourceCodeStart":70,"sourceCodeEnd":106,"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/AbstractNodeDataConverter.java#L70-L106","documentation":"Thrown by AbstractNodeDataConverter.varTemplateToSelector when the template string passed is null. A null variable template cannot be parsed into a VariableSelector, so the method fails fast with an NPE rather than returning a broken selector.","triggerScenarios":"Converting a node's variable template field that is absent in the source DSL (e.g. a node without a variable reference) and passing the null template straight into varTemplateToSelector.","commonSituations":"DSL nodes with missing/optional variable fields, converters not checking for optional templates before calling the helper.","solutions":["Null-check the template before calling varTemplateToSelector and skip/return null selector for absent variables","Fix the source DSL so the variable template field is populated","Default the template to an empty string if the node legitimately has no variable"],"exampleFix":"// before\nVariableSelector sel = varTemplateToSelector(dialect, nodeData.getTemplate());\n// after\nVariableSelector sel = nodeData.getTemplate() == null ? null\n    : varTemplateToSelector(dialect, nodeData.getTemplate());\n","handlingStrategy":"type-guard","validationCode":"if (template == null) { return null; } // skip optional variable","typeGuard":"VariableSelector safeSelector(DSLDialectType d, String t) { return t == null ? null : varTemplateToSelector(d, t); }","tryCatchPattern":"try { sel = varTemplateToSelector(dialect, template); } catch (NullPointerException e) { sel = null; /* node has no variable */ }","preventionTips":["Treat variable templates as optional and null-check first","Normalize absent DSL fields to empty strings in converters","Add converter tests for nodes without variables"],"tags":["null-argument","dsl","template-parsing"],"backgroundTag":"null-argument","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"}