{"record":{"id":"66a205f5548a33a0","repo":"quarkusio/quarkus","slug":"metadata-key-already-exists","errorCode":null,"errorMessage":"Metadata key already exists: ","messagePattern":"Metadata key already exists: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/signals/runtime/src/main/java/io/quarkus/signals/runtime/impl/SignalImpl.java","lineNumber":261,"sourceCode":"\n    static class EnrichmentContextImpl implements SignalMetadataEnricher.EnrichmentContext {\n\n        private final SignalContext<?> signalContext;\n        private Map<String, Object> additions;\n\n        EnrichmentContextImpl(SignalContext<?> signalContext) {\n            this.signalContext = signalContext;\n        }\n\n        @Override\n        public SignalContext<?> signalContext() {\n            return signalContext;\n        }\n\n        @Override\n        public void putMetadata(String key, Object value) {\n            if (signalContext.metadata().containsKey(key)) {\n                throw new IllegalArgumentException(\"Metadata key already exists: \" + key);\n            }\n            if (additions == null) {\n                additions = new HashMap<>();\n            }\n            if (additions.putIfAbsent(key, value) != null) {\n                throw new IllegalArgumentException(\"Metadata key already exists: \" + key);\n            }\n        }\n\n        Map<String, Object> additions() {\n            return additions != null ? additions : Map.of();\n        }\n    }\n\n    class SignalContextImpl<SIGNAL> implements SignalContext<SIGNAL> {\n\n        private final SIGNAL signal;\n        private final Map<String, Object> meta;","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/signals/runtime/src/main/java/io/quarkus/signals/runtime/impl/SignalImpl.java#L243-L279","documentation":"SignalContext.putMetadata refuses to overwrite an existing metadata key: if the key is already present in the signal's existing metadata map, the call throws IllegalArgumentException. Metadata is write-once, so callers must use unique keys per signal context.","triggerScenarios":"Calling putMetadata(key, value) with a key that already exists in signalContext.metadata() — typically a hardcoded key set earlier in the pipeline or by another participant of the same signal.","commonSituations":"Two interceptors/filters writing the same metadata key (e.g. \"traceId\"); re-invoking processing logic on the same context; framework code reserving keys an application also tries to set.","solutions":["Use a distinct, namespaced key (e.g. prefix with your application/module name)","Check containsKey() or read the existing value first and skip the put when present","If overwriting is intended, restructure to compose values instead of re-putting the same key"],"exampleFix":"// before\ncontext.putMetadata(\"traceId\", id);\n// after\nif (!context.metadata().containsKey(\"myapp.traceId\")) {\n    context.putMetadata(\"myapp.traceId\", id);\n}","handlingStrategy":"type-guard","validationCode":"if (context.metadata().containsKey(key)) return; // or compose with existing value","typeGuard":"boolean canPut(SignalContext ctx, String key) { return !ctx.metadata().containsKey(key); }","tryCatchPattern":"try { ctx.putMetadata(key, value); }\ncatch (IllegalArgumentException e) { log.warnf(\"Metadata key %s already set: %s\", key, e.getMessage()); }","preventionTips":["Namespace metadata keys with your application prefix","Treat metadata as write-once; compute values once per context","Check metadata() before adding in shared/interceptor code"],"tags":["metadata","duplicate-key","signals"],"backgroundTag":"duplicate-metadata-key","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}