{"record":{"id":"23b3fe250d89a455","repo":"apache/cassandra","slug":"threadgroup-may-only-be-overridden-with-a-child-of","errorCode":null,"errorMessage":"threadGroup may only be overridden with a child of the default threadGroup","messagePattern":"threadGroup may only be overridden with a child of the default threadGroup","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/concurrent/ThreadPoolExecutorBuilder.java","lineNumber":118,"sourceCode":"        return this;\n    }\n\n    public ThreadPoolExecutorBuilder<E> withThreadPriority(int threadPriority)\n    {\n        this.threadPriority = threadPriority;\n        return this;\n    }\n\n    @Override\n    public ExecutorBuilder<E> withThreadGroup(ThreadGroup threadGroup)\n    {\n        ThreadGroup current = this.threadGroup;\n\n        ThreadGroup parent = threadGroup;\n        while (parent != null && parent != current)\n            parent = parent.getParent();\n        if (parent != current)\n            throw new IllegalArgumentException(\"threadGroup may only be overridden with a child of the default threadGroup\");\n\n        this.threadGroup = threadGroup;\n        return this;\n    }\n\n    @Override\n    public ExecutorBuilder<E> withDefaultThreadGroup()\n    {\n        this.threadGroup = null;\n        return this;\n    }\n\n    public ThreadPoolExecutorBuilder<E> withQueueLimit(int queueLimit)\n    {\n        this.queueLimit = queueLimit;\n        return this;\n    }\n","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/concurrent/ThreadPoolExecutorBuilder.java#L100-L136","documentation":"Thrown by ThreadPoolExecutorBuilder.withThreadGroup when the supplied ThreadGroup is not the current default threadGroup itself nor a child (direct or nested) of it. Cassandra only permits narrowing the thread group within its default group to keep pool threads manageable.","triggerScenarios":"Calling withThreadGroup() on a builder with a ThreadGroup created outside the default group's hierarchy, e.g. a fresh new ThreadGroup(\"...\") with no parent linkage to the default group.","commonSituations":"Embedding Cassandra or its wrappers in application servers that use custom root ThreadGroups, refactoring pool creation code and constructing a standalone ThreadGroup.","solutions":["Pass a ThreadGroup that is a child of the default thread group (create it with new ThreadGroup(defaultGroup, name))","Omit withThreadGroup() entirely to inherit the default","If a fully separate group is required, attach it to the default group first via setParent-like construction or restructure the threading model"],"exampleFix":"// before\nbuilder.withThreadGroup(new ThreadGroup(\"my-pool\"));\n// after\nbuilder.withThreadGroup(new ThreadGroup(Thread.currentThread().getThreadGroup(), \"my-pool\"));","handlingStrategy":"validation","validationCode":"ThreadGroup current = Thread.currentThread().getThreadGroup();\nThreadGroup parent = candidate;\nwhile (parent != null && parent != current) parent = parent.getParent();\nboolean allowed = (parent == current);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always parent custom ThreadGroups to the default/current group","Skip withThreadGroup() unless you truly need sub-grouping","Never construct orphan ThreadGroups for pool threads"],"tags":["concurrency","threadpool","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}