{"record":{"id":"f8a796981b6fac94","repo":"alibaba/spring-ai-alibaba","slug":"maxcachedthreads-must-be-greater-than-or-equal-to-f8a796","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/mysql/MysqlSaver.java","lineNumber":600,"sourceCode":"\n\t/**\n\t * A builder for MysqlSaver.\n\t */\n\tpublic static class Builder {\n\t\tprivate DataSource dataSource;\n\t\tprivate CreateOption createOption = CreateOption.CREATE_IF_NOT_EXISTS;\n\t\tprivate StateSerializer stateSerializer;\n\t\tprivate int maxCachedThreads = 1024;\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 * 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 datasource","sourceCodeStart":582,"sourceCodeEnd":618,"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/mysql/MysqlSaver.java#L582-L618","documentation":"Builder.maxCachedThreads(int) validates its argument and throws IllegalArgumentException if a negative value is passed. The cache of thread states can be disabled with 0, but any negative count is invalid.","triggerScenarios":"Calling MysqlSaver.builder().maxCachedThreads(-1) (or computing the value from a config/property that resolves negative, e.g. an int parsed from a bad environment variable) before build().","commonSituations":"Feeding maxCachedThreads from external configuration where a sentinel like -1 meant 'unlimited' in the developer's own config convention; arithmetic producing a negative value; typos in config keys shifting values.","solutions":["Pass a non-negative integer; use 0 to disable the thread cache entirely.","Clamp or validate externally supplied config values before passing them to the builder.","Map a '-1 means unlimited' convention to a large positive number or to 0 explicitly before building."],"exampleFix":"// before\nint threads = Integer.parseInt(env.getProperty(\"cache.threads\")); // -1 = unlimited convention\nMysqlSaver.builder().maxCachedThreads(threads); // IllegalArgumentException\n// after\nint threads = Math.max(0, Integer.parseInt(env.getProperty(\"cache.threads\", \"0\")));\nMysqlSaver.builder().maxCachedThreads(threads);","handlingStrategy":"validation","validationCode":"int t = config.maxCachedThreads();\nif (t < 0) t = 0; // or map your '-1 = unlimited' convention explicitly\nbuilder.maxCachedThreads(t);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never feed builder methods raw external config without clamping.","Remember 0 disables the cache; negative values are always rejected.","Add unit tests for config-to-builder value mapping."],"tags":["builder","validation","illegal-argument","configuration"],"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"}