{"record":{"id":"a1856fd1dc0f44b1","repo":"netty/netty","slug":"can-t-add-to-itself","errorCode":null,"errorMessage":"can't add to itself.","messagePattern":"can't add to itself\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"codec-base/src/main/java/io/netty/handler/codec/DefaultHeaders.java","lineNumber":479,"sourceCode":"    @Override\n    public T addFloat(K name, float value) {\n        return add(name, fromFloat(name, value));\n    }\n\n    @Override\n    public T addByte(K name, byte value) {\n        return add(name, fromByte(name, value));\n    }\n\n    @Override\n    public T addShort(K name, short value) {\n        return add(name, fromShort(name, value));\n    }\n\n    @Override\n    public T add(Headers<? extends K, ? extends V, ?> headers) {\n        if (headers == this) {\n            throw new IllegalArgumentException(\"can't add to itself.\");\n        }\n        addImpl(headers);\n        return thisT();\n    }\n\n    protected void addImpl(Headers<? extends K, ? extends V, ?> headers) {\n        if (headers instanceof DefaultHeaders) {\n            @SuppressWarnings(\"unchecked\")\n            final DefaultHeaders<? extends K, ? extends V, T> defaultHeaders =\n                    (DefaultHeaders<? extends K, ? extends V, T>) headers;\n            HeaderEntry<? extends K, ? extends V> e = defaultHeaders.head.after;\n            if (defaultHeaders.hashingStrategy == hashingStrategy &&\n                    defaultHeaders.nameValidator == nameValidator) {\n                // Fastest copy\n                while (e != defaultHeaders.head) {\n                    add0(e.hash, index(e.hash), e.key, e.value);\n                    e = e.after;\n                }","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/netty/netty/blob/70040aacae241e9ba371e758f5b86e470bd77ad1/codec-base/src/main/java/io/netty/handler/codec/DefaultHeaders.java#L461-L497","documentation":"Thrown by DefaultHeaders.add(Headers) when the argument is the same instance as 'this' (headers == this). Adding a collection to itself would cause infinite recursion or concurrent modification in the linked-list traversal during addImpl(), so Netty rejects it explicitly. The check is a reference equality (==) check, not a deep equality check.","triggerScenarios":"Calling headers.add(headers) — passing the same DefaultHeaders instance as both source and destination. Occurs in code that copies headers between collections and accidentally passes the source as its own target, or in aggregation/merge logic where the same reference appears on both sides.","commonSituations":"Header merging/aggregation code where src and dst resolve to the same object due to a logic bug; conditional code paths that sometimes pass the same headers reference; refactoring that changed ownership semantics; a method that receives headers as a parameter and also returns to the same caller.","solutions":["Before calling add(), check reference equality: if (source != target) target.add(source).","If you need to duplicate entries within the same headers, iterate manually and add each entry.","Use a separate headers instance as the merge destination."],"exampleFix":"// before\nif (needsMerge) {\n    headers.add(headers); // self-reference\n}\n\n// after\nif (needsMerge && other != headers) {\n    headers.add(other);\n}","handlingStrategy":"validation","validationCode":"// Prevent self-addition\npublic void mergeHeaders(DefaultHeaders<K, V, T> target, Headers<K, V, ?> source) {\n    if (source == target) {\n        throw new IllegalArgumentException(\"Cannot merge headers into itself\");\n    }\n    target.add(source);\n}","typeGuard":"static <K, V> boolean isSelfReference(\n        DefaultHeaders<K, V, ?> target, Headers<K, V, ?> source) {\n    return source == target;\n}","tryCatchPattern":"try {\n    headers.add(source);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"can't add to itself\")) {\n        // copy entries individually instead\n        for (Map.Entry<K, V> entry : source) {\n            headers.add(entry.getKey(), entry.getValue());\n        }\n    }\n}","preventionTips":["Always check source != target before calling add().","Use a separate destination instance for merge operations.","Be careful with conditional merge paths that may resolve to the same reference."],"tags":["netty","codec","headers","precondition","self-reference"],"backgroundTag":null,"analyzedSha":"70040aacae241e9ba371e758f5b86e470bd77ad1","analyzedAt":"2026-08-14T01:29:15.551Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}