{"record":{"id":"f836ba174425218c","repo":"quarkusio/quarkus","slug":"calling-injectinterceptionproxy-more-than-once-i","errorCode":null,"errorMessage":"Calling injectInterceptionProxy() more than once is invalid","messagePattern":"Calling injectInterceptionProxy\\(\\) more than once is invalid","errorType":"exception","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanConfiguratorBase.java","lineNumber":428,"sourceCode":"\n    /**\n     * Declares that this synthetic bean has an injection point of type {@code InterceptionProxy<PT>},\n     * where {@code PT} is the {@linkplain #providerType(Type) provider type} of this bean.\n     * An instance of {@code PT} may be used as a parameter to {@link InterceptionProxy#create(Object)}\n     * in the {@linkplain BeanCreator creator} of this synthetic bean.\n     * <p>\n     * If the {@code bindingsSource} is not {@code null}, interceptor bindings on the class\n     * of the provider type are ignored; instead, the {@code bindingsSource} class is scanned\n     * for interceptor binding annotations as defined in {@link io.quarkus.arc.BindingsSource}.\n     * <p>\n     * This method may only be called once. Subsequent calls throw an exception.\n     *\n     * @param bindingsSource the bindings source class, may be {@code null}\n     * @return self\n     */\n    public THIS injectInterceptionProxy(DotName bindingsSource) {\n        if (interceptionProxy != null) {\n            throw new DefinitionException(\"Calling injectInterceptionProxy() more than once is invalid\");\n        }\n        interceptionProxy = new InterceptionProxyInfo(bindingsSource);\n        return self();\n    }\n\n    public <U extends T> THIS creator(Class<? extends BeanCreator<U>> creatorClazz) {\n        return creator(cg -> {\n            BlockCreator bc = cg.createMethod();\n\n            // return new FooBeanCreator().create(syntheticCreationalContext)\n            MethodDesc createDesc = MethodDesc.of(BeanCreator.class, \"create\", Object.class, SyntheticCreationalContext.class);\n            bc.return_(bc.invokeInterface(createDesc, bc.new_(creatorClazz), cg.syntheticCreationalContext()));\n        });\n    }\n\n    /**\n     * The first method parameter is the synthetic creational context, i.e. the {@code MethodCreator#getMethodParam(0)} returns\n     * a {@link SyntheticCreationalContext} instance that can be used to obtain contextual references for synthetic injection","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanConfiguratorBase.java#L410-L446","documentation":"BeanConfiguratorBase.injectInterceptionProxy() registers an interception proxy for a synthetic bean and must be called at most once per configurator. A second call means the interceptionProxy field is already set, so Arc throws DefinitionException to prevent silently overwriting the interception configuration.","triggerScenarios":"Calling beanConfigurator.injectInterceptionProxy(...) twice on the same synthetic bean configurator — typically in shared registrar code paths executed more than once, or two extension registrations both adding an interception proxy to the same bean.","commonSituations":"Synthetic bean registrars with duplicated/conditional code paths; multiple extensions contributing to the same synthetic bean; copy-paste in an ObserverRegistrar/SyntheticBeanRegistrar.","solutions":["Guard with a flag/check before calling injectInterceptionProxy, or restructure so it's invoked exactly once per configurator","If you need different bindings, replace the configurator rather than re-adding — create a new BeanConfigurator","Audit extension registrar implementations for duplicate registration of the same synthetic bean"],"exampleFix":"// before\nconfig.injectInterceptionProxy(BindingsA.class);\nif (extra) config.injectInterceptionProxy(BindingsB.class); // throws\n// after\nconfig.injectInterceptionProxy(extra ? BindingsB.class : BindingsA.class);","handlingStrategy":"validation","validationCode":"if (config.interceptionProxyConfigured()) { throw new IllegalStateException(\"interception proxy already set\"); }\nconfig.injectInterceptionProxy(bindingsSource);","typeGuard":null,"tryCatchPattern":"try { config.injectInterceptionProxy(src); }\ncatch (DefinitionException e) { log.error(\"injectInterceptionProxy called twice on same configurator\", e); throw e; }","preventionTips":["Call injectInterceptionProxy exactly once, in a single code path","Guard shared registrar helpers against re-entry","Review synthetic bean registrations for duplicate contribution of the same bean"],"tags":["cdi","arc","interception-proxy","synthetic-bean","duplicate-call"],"backgroundTag":"method-called-twice","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}