{"record":{"id":"3e7d286b69c16144","repo":"apache/druid","slug":"key-s-has-already-been-registered-as-a-context","errorCode":null,"errorMessage":"Key [%s] has already been registered as a context key","messagePattern":"Key \\[(.+?)\\] has already been registered as a context key","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/context/ResponseContext.java","lineNumber":519,"sourceCode":"    }\n\n    /**\n     * Returns the single, global key registry for this server.\n     */\n    public static Keys instance()\n    {\n      return INSTANCE;\n    }\n\n    /**\n     * Primary way of registering context keys.\n     *\n     * @throws IllegalArgumentException if the key has already been registered.\n     */\n    public void registerKey(Key key)\n    {\n      if (registeredKeys.putIfAbsent(key.getName(), key) != null) {\n        throw new IAE(\"Key [%s] has already been registered as a context key\", key.getName());\n      }\n    }\n\n    /**\n     * Register a group of keys.\n     */\n    public void registerKeys(Key[] keys)\n    {\n      for (Key key : keys) {\n        registerKey(key);\n      }\n    }\n\n    /**\n     * Returns a registered key associated with the name {@param name}.\n     *\n     * @throws IllegalStateException if a corresponding key has not been registered.\n     */","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/context/ResponseContext.java#L501-L537","documentation":"ResponseContext.BaseResponseContext.registerKey maintains a registry of valid context keys and throws IllegalArgumentException when a key with the same name is already registered. This protects against duplicate definitions of response context keys across server components.","triggerScenarios":"Calling registerKey (directly or via registerKeys) with a Key whose getName() collides with a previously registered key, e.g. two extensions registering the same response context key name.","commonSituations":"Two Druid extensions or modules defining response header/context keys with identical names; re-registering keys during component restart without checking the registry; duplicate constant definitions after a merge.","solutions":["Check keyOf(name)/registration before calling registerKey, or register only once at static initialization","Rename your key to a unique, namespaced string (e.g. prefix with extension name)","Catch IllegalArgumentException from registerKey and treat it as a no-op if the existing key is equivalent","Register all keys together via registerKeys at a single well-defined initialization point"],"exampleFix":"// before\nresponseContext.registerKey(MY_KEY);\nresponseContext.registerKey(MY_KEY); // IAE\n// after\nif (responseContext.keyOfOrNull(MY_KEY.getName()) == null) {\n  responseContext.registerKey(MY_KEY);\n}","handlingStrategy":"try-catch","validationCode":"// guard against duplicate registration\nif (context.keyOfOrNull(key.getName()) == null) {\n  context.registerKey(key);\n}","typeGuard":"boolean isRegistered(ResponseContext ctx, String name) { return ctx.keyOfOrNull(name) != null; }","tryCatchPattern":"try { ctx.registerKey(key); } catch (IllegalArgumentException e) { log.debug(\"key already registered: %s\", key.getName()); }","preventionTips":["Namespace key names with extension/module prefix","Register keys once in static initialization or module setup","Use keyOfOrNull to probe before registering"],"tags":["java","query-context","duplicate-key"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}