{"record":{"id":"9d4c60845f0cda1a","repo":"alibaba/spring-ai-alibaba","slug":"s-cannot-be-blank","errorCode":null,"errorMessage":"'%s' cannot be blank","messagePattern":"'(.+?)' cannot be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java","lineNumber":566,"sourceCode":"\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder createOption(CreateOption createOption) {\n\t\t\tthis.createOption = requireNonNull(createOption, \"createOption cannot be null\");\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder maxCachedThreads(int maxCachedThreads) {\n\t\t\tif (maxCachedThreads < 0) {\n\t\t\t\tthrow new IllegalArgumentException(\"maxCachedThreads must be greater than or equal to 0\");\n\t\t\t}\n\t\t\tthis.maxCachedThreads = maxCachedThreads;\n\t\t\treturn this;\n\t\t}\n\n\t\tprivate String requireNotBlank(String value, String name) {\n\t\t\tif (requireNonNull(value, format(\"'%s' cannot be null\", name)).isBlank()) {\n\t\t\t\tthrow new IllegalArgumentException(format(\"'%s' cannot be blank\", name));\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic H2Saver build() {\n\t\t\tif (stateSerializer == null) {\n\t\t\t\tthis.stateSerializer = StateGraph.DEFAULT_JACKSON_SERIALIZER;\n\t\t\t}\n\t\t\tif (dataSource == null) {\n\t\t\t\tdataSource = new DriverManagerDataSource(requireNotBlank(jdbcUrl, \"jdbcUrl\"), user, password);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn new H2Saver(this);\n\t\t\t}\n\t\t\tcatch (SQLException ex) {\n\t\t\t\tthrow new RuntimeException(ex);\n\t\t\t}\n\t\t}","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java#L548-L584","documentation":"Builder.requireNotBlank is the internal guard used by database() and build() for string options; it throws IllegalArgumentException(\"'%s' cannot be blank\") when the value is null-or-blank (null yields a 'cannot be null' message via requireNonNull instead). It ensures the H2 database identifier/name is a real value before constructing the saver.","triggerScenarios":"Calling builder.database(null/\"\"/\"   \") or build() with any required string option left blank — the guard fires with the option's name in the message.","commonSituations":"Config property for the database name missing or whitespace-only; YAML property bound to an empty string; empty env variable interpolated into the builder call.","solutions":["Supply a non-blank value for the named option before calling build().","Validate configuration at startup: reject blank values with a clear message before reaching the builder.","Use Spring's @Validated/@NotBlank on config properties so the failure surfaces at context startup."],"exampleFix":"// before: blank config value flows into builder\nH2Saver.builder().database(props.db()).build(); // IllegalArgumentException\n// after: validate first\nif (props.db() == null || props.db().isBlank()) throw new IllegalStateException(\"h2 database name required\");\nH2Saver.builder().database(props.db()).build();","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(db, \"h2 database name required\"); if (db.isBlank()) throw new IllegalArgumentException(\"h2 database name required\");","typeGuard":"Optional<String> nonBlank(String s) { return Optional.ofNullable(s).map(String::strip).filter(v -> !v.isEmpty()); }","tryCatchPattern":"try { H2Saver saver = builder.database(db).build(); }\ncatch (IllegalArgumentException e) { throw new IllegalStateException(\"invalid H2 saver config: \" + e.getMessage(), e); }","preventionTips":["Validate config properties with @NotBlank at startup","Fail fast on blank env vars before building infrastructure objects","Trim externally-supplied values before passing to builders"],"tags":["builder","validation","configuration","blank-value"],"backgroundTag":"empty-required-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"}