{"record":{"id":"837945c72cb30106","repo":"alibaba/spring-ai-alibaba","slug":"maxcachedthreads-must-be-greater-than-or-equal-to-837945","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/postgresql/PostgresSaver.java","lineNumber":636,"sourceCode":"\t\tprivate DataSource datasource;\n\n\t\t// New CreateOption field with default value\n\t\tprivate CreateOption createOption = CreateOption.CREATE_IF_NOT_EXISTS;\n\n\t\tprivate int maxCachedThreads = 1024;\n\n\t\t// Legacy fields for backward compatibility\n\t\tprivate boolean createTables;\n\t\tprivate boolean dropTablesFirst;\n\n\t\t/**\n\t\t * Sets the maximum number of latest checkpoints retained in memory.\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\tpublic Builder stateSerializer(StateSerializer stateSerializer) {\n\t\t\tthis.stateSerializer = stateSerializer;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder host(String host) {\n\t\t\tthis.host = host;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder port(Integer port) {\n\t\t\tthis.port = port;\n\t\t\treturn this;","sourceCodeStart":618,"sourceCodeEnd":654,"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/postgresql/PostgresSaver.java#L618-L654","documentation":"Builder.maxCachedThreads validates that the in-memory checkpoint cache size is non-negative; passing a negative value throws this IllegalArgumentException immediately at builder time. 0 is allowed and disables the cache.","triggerScenarios":"PostgresSaver.builder().maxCachedThreads(-1) or computing the value from config (e.g. env var or properties) that yields a negative number.","commonSituations":"Misconfigured property like 'checkpoint.cache-size=-10'; sign error when computing 'max - used'; unparsed/default sentinel values like -1 meaning 'unlimited'.","solutions":["Pass a value >= 0; use 0 to explicitly disable the cache.","Clamp or sanitize external config before passing: Math.max(0, configuredValue).","Fix the configuration source (env var / application.properties) supplying the negative number."],"exampleFix":"// before\nbuilder.maxCachedThreads(Integer.parseInt(env.get(\"CACHE_SIZE\"))); // -1 possible\n// after\nint cacheSize = Math.max(0, Integer.parseInt(env.getOrDefault(\"CACHE_SIZE\", \"0\")));\nbuilder.maxCachedThreads(cacheSize);","handlingStrategy":"validation","validationCode":"int v = Integer.parseInt(cfg.get(\"cacheSize\"));\nif (v < 0) throw new IllegalArgumentException(\"cacheSize must be >= 0\");\nbuilder.maxCachedThreads(v);","typeGuard":null,"tryCatchPattern":"try { builder.maxCachedThreads(v); } catch (IllegalArgumentException e) { builder.maxCachedThreads(0); }","preventionTips":["Clamp external config with Math.max(0, value)","Never use -1 as 'unlimited' sentinel","Validate config at startup"],"tags":["configuration","builder-validation","checkpoint"],"backgroundTag":"invalid-config-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"}