{"record":{"id":"7a2ee85c832b7dd0","repo":"ruby-concurrency/concurrent-ruby","slug":"illegalargumentexception","errorCode":null,"errorMessage":"IllegalArgumentException","messagePattern":"IllegalArgumentException","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java","lineNumber":2536,"sourceCode":"     * Creates a new, empty map with the default initial table size (16).\n     */\n    public ConcurrentHashMapV8() {\n        this.counter = new LongAdder();\n    }\n\n    /**\n     * Creates a new, empty map with an initial table size\n     * accommodating the specified number of elements without the need\n     * to dynamically resize.\n     *\n     * @param initialCapacity The implementation performs internal\n     * sizing to accommodate this many elements.\n     * @throws IllegalArgumentException if the initial capacity of\n     * elements is negative\n     */\n    public ConcurrentHashMapV8(int initialCapacity) {\n        if (initialCapacity < 0)\n            throw new IllegalArgumentException();\n        int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?\n                MAXIMUM_CAPACITY :\n                tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));\n        this.counter = new LongAdder();\n        this.sizeCtl = cap;\n    }\n\n    /**\n     * Creates a new map with the same mappings as the given map.\n     *\n     * @param m the map\n     */\n    public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {\n        this.counter = new LongAdder();\n        this.sizeCtl = DEFAULT_CAPACITY;\n        internalPutAll(m);\n    }\n","sourceCodeStart":2518,"sourceCodeEnd":2554,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java#L2518-L2554","documentation":"The single-argument constructor treats initialCapacity as a sizing hint and converts it to a power-of-two table size via tableSizeFor. A negative capacity cannot be a table size, so the constructor throws IllegalArgumentException before any table is allocated. The exception carries no message; the stack frame at this constructor line is the only diagnostic.","triggerScenarios":"new ConcurrentHashMapV8<K,V>(-1); passing a computed size such as expected - slack that underflows below zero; forwarding a configuration value that uses -1 as its unset sentinel straight into the constructor.","commonSituations":"Plumbing capacity from YAML/env/config where the default is -1 meaning not-set; boundary-value unit tests; refactoring HashMap initialCapacity code paths into the concurrent map during a caching migration.","solutions":["Clamp before constructing: use Math.max(0, requestedCapacity) or fall back to a default like 16 when negative","Validate numeric configuration once at load time and fail fast with a clear message instead of at first construction","Treat the -1 sentinel as an instruction to use the no-arg constructor"],"exampleFix":"// before\nint cap = configuredCapacity; // -1 when unset\nnew ConcurrentHashMapV8<String,String>(cap);\n\n// after\nint cap = configuredCapacity > 0 ? configuredCapacity : 16;\nnew ConcurrentHashMapV8<String,String>(cap);","handlingStrategy":"validation","validationCode":"int cap = (configuredCapacity != null && configuredCapacity > 0) ? configuredCapacity : DEFAULT_CAPACITY;\n// then construct with cap","typeGuard":null,"tryCatchPattern":"try { new ConcurrentHashMapV8<K,V>(cap); } catch (IllegalArgumentException e) { throw new ConfigException(cap); }","preventionTips":["Validate numeric config once at startup, not at each construction","Convert the -1 unset sentinel to a default before constructing","Clamp any arithmetic on sizes before passing them as capacity"],"tags":["constructor","capacity","illegal-argument","validation"],"backgroundTag":"negative-initial-capacity","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}