{"record":{"id":"b661578fa6d88fc0","repo":"alibaba/spring-ai-alibaba","slug":"maxcachedthreads-must-be-greater-than-or-equal-to-b66157","errorCode":null,"errorMessage":"maxCachedThreads must be greater than or equal to 0","messagePattern":"maxCachedThreads must be greater than or equal to 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/oracle/OracleSaver.java","lineNumber":633,"sourceCode":"\t\t * Sets the state serializer\n\t\t *\n\t\t * @param stateSerializer the state serializer\n\t\t * @return this builder\n\t\t */\n\t\tpublic Builder stateSerializer(StateSerializer stateSerializer) {\n\t\t\tthis.stateSerializer = stateSerializer;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Sets the maximum number of latest checkpoints retained in memory.\n\t\t *\n\t\t * @param maxCachedThreads max cached threads, or 0 to disable the cache\n\t\t * @return this builder\n\t\t */\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\t/**\n\t\t * Creates a new instance of OracleSaver\n\t\t *\n\t\t * @return the new instance of OracleSaver.\n\t\t */\n\t\tpublic OracleSaver build() {\n\t\t\tObjects.requireNonNull(dataSource, \"dataSource cannot be null\");\n\t\t\tif (stateSerializer == null) {\n\t\t\t\tthis.stateSerializer = StateGraph.DEFAULT_JACKSON_SERIALIZER;\n\t\t\t}\n\t\t\treturn new OracleSaver(this);\n\t\t}\n\t}","sourceCodeStart":615,"sourceCodeEnd":651,"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/oracle/OracleSaver.java#L615-L651","documentation":"OracleSaver.Builder.maxCachedThreads validates that the configured thread-cache size is non-negative; a negative value throws IllegalArgumentException('maxCachedThreads must be greater than or equal to 0'). A value of 0 disables the cache, so any negative number is meaningless and rejected at build time.","triggerScenarios":"Calling OracleSaver.Builder.maxCachedThreads(-1) (or any negative int) before build().","commonSituations":"Computing the cache size from a config value or formula that can go negative (e.g. maxThreads - overhead) and passing it unvalidated.","solutions":["Pass a value >= 0; use 0 to disable the thread cache.","Clamp the value before setting: Math.max(0, configuredValue).","Fix the source config/formula that produced a negative number."],"exampleFix":"// before\nint threads = config.getMaxThreads() - reserved;\nbuilder.maxCachedThreads(threads); // throws if negative\n// after\nbuilder.maxCachedThreads(Math.max(0, config.getMaxThreads() - reserved));","handlingStrategy":"validation","validationCode":"// Java: validate before calling builder\nif (configuredThreads < 0) {\n    throw new ConfigurationException(\"maxCachedThreads must be >= 0, got \" + configuredThreads);\n}\nbuilder.maxCachedThreads(configuredThreads);","typeGuard":null,"tryCatchPattern":"try {\n    builder.maxCachedThreads(threads);\n} catch (IllegalArgumentException e) {\n    builder.maxCachedThreads(0); // fall back to disabled cache\n}","preventionTips":["Clamp computed values with Math.max(0, value).","Validate config at startup, before constructing the saver.","Remember 0 legitimately disables the cache; never use negative sentinels."],"tags":["oracle","builder","validation","illegal-argument"],"backgroundTag":"invalid-argument-value","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"}