{"record":{"id":"104af450228794b7","repo":"alibaba/druid","slug":"tocount-can-t-not-be-less-than-zero","errorCode":null,"errorMessage":"toCount can't not be less than zero","messagePattern":"toCount can't not be less than zero","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java","lineNumber":3818,"sourceCode":"        if (poolingCount == 0) {\n            return null;\n        }\n        return getConnection();\n    }\n\n    @Override\n    public int fill() throws SQLException {\n        return this.fill(this.maxActive);\n    }\n\n    @Override\n    public int fill(int toCount) throws SQLException {\n        if (closed) {\n            throw new DataSourceClosedException(\"dataSource already closed at \" + new Date(closeTimeMillis));\n        }\n\n        if (toCount < 0) {\n            throw new IllegalArgumentException(\"toCount can't not be less than zero\");\n        }\n\n        init();\n\n        if (toCount > this.maxActive) {\n            toCount = this.maxActive;\n        }\n\n        int fillCount = 0;\n        for (; ; ) {\n            try {\n                lock.lockInterruptibly();\n            } catch (InterruptedException e) {\n                connectErrorCountUpdater.incrementAndGet(this);\n                throw new SQLException(\"interrupt\", e);\n            }\n\n            boolean fillable = this.isFillable(toCount);","sourceCodeStart":3800,"sourceCodeEnd":3836,"githubUrl":"https://github.com/alibaba/druid/blob/fa8dc9912637a2f729eef9f55356621fec18d40e/core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java#L3800-L3836","documentation":"IllegalArgumentException thrown by fill(int toCount) when toCount is negative. fill() is meant to grow the pool to a target number of idle connections, so a negative target is a programmer error and is rejected before any physical connection is opened.","triggerScenarios":"dataSource.fill(-1) (or any toCount < 0) — the guard at line 3817 throws. Typically the result of a computed count underflowing to negative (e.g. maxActive - someDelta where delta > maxActive).","commonSituations":"Arithmetic producing a negative target (maxActive - headroom with headroom larger than maxActive); passing a config value that was unset and defaulted to -1; a unit test passing a sentinel; an off-by-one in a warm-up loop decrementing the target.","solutions":["Clamp the computed toCount to at least 0 (or a sensible minimum) before calling fill().","If you want 'fill to maxActive', call the no-arg fill() which does fill(this.maxActive) and never passes a negative.","Validate configuration at startup: reject negative values for any pool-sizing property feeding fill()."],"exampleFix":"// before\nint target = desiredIdle - extra;     // extra > desiredIdle -> target < 0\nddataSource.fill(target); // IllegalArgumentException\n\n// after\nddataSource.fill(Math.max(0, target));","handlingStrategy":"validation","validationCode":"if (toCount < 0) {\n    throw new IllegalArgumentException(\"toCount must be >= 0, got \" + toCount);\n}\nreturn dataSource.fill(Math.min(toCount, ((DruidDataSource) dataSource).getMaxActive()));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed fill targets with Math.max(0, x).","Prefer the no-arg fill() which uses maxActive and can never be negative.","Validate pool-sizing config at startup."],"tags":["validation","fill","argument-check","config","programming-error"],"backgroundTag":null,"analyzedSha":"fa8dc9912637a2f729eef9f55356621fec18d40e","analyzedAt":"2026-08-14T04:55:06.789Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}