{"id":"30559adceb3d4a0a","repo":"spring-projects/spring-framework","slug":"cannot-remove-advisor-configuration-is-frozen","errorCode":null,"errorMessage":"Cannot remove Advisor: Configuration is frozen.","messagePattern":"Cannot remove Advisor: Configuration is frozen\\.","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java","lineNumber":330,"sourceCode":"\t\taddAdvisorInternal(pos, advisor);\n\t}\n\n\t@Override\n\tpublic boolean removeAdvisor(Advisor advisor) {\n\t\tint index = indexOf(advisor);\n\t\tif (index == -1) {\n\t\t\treturn false;\n\t\t}\n\t\telse {\n\t\t\tremoveAdvisor(index);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void removeAdvisor(int index) throws AopConfigException {\n\t\tif (isFrozen()) {\n\t\t\tthrow new AopConfigException(\"Cannot remove Advisor: Configuration is frozen.\");\n\t\t}\n\t\tif (index < 0 || index > this.advisors.size() - 1) {\n\t\t\tthrow new AopConfigException(\"Advisor index \" + index + \" is out of bounds: \" +\n\t\t\t\t\t\"This configuration only has \" + this.advisors.size() + \" advisors.\");\n\t\t}\n\n\t\tAdvisor advisor = this.advisors.remove(index);\n\t\tif (advisor instanceof IntroductionAdvisor introductionAdvisor) {\n\t\t\t// We need to remove introduction interfaces.\n\t\t\tfor (Class<?> ifc : introductionAdvisor.getInterfaces()) {\n\t\t\t\tremoveInterface(ifc);\n\t\t\t}\n\t\t}\n\n\t\tadviceChanged();\n\t}\n\n\t@Override","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java#L312-L348","documentation":"Thrown by AdvisedSupport.removeAdvisor(int) when isFrozen() returns true. A frozen AdvisedSupport cannot have its advisor list mutated; freezing is used by the framework (e.g. after proxy creation in optimized or frozen mode) to lock the advisor chain for performance and correctness. Any runtime attempt to remove an advisor from a frozen configuration is rejected.","triggerScenarios":"Calling advised.removeAdvisor(i) on a proxy whose ProxyConfig had setFrozen(true); calling it on an already-constructed proxy where the framework froze the config internally; calling on a frozen prototype snapshot obtained from getConfigurationOnlyCopy().","commonSituations":"User code that dynamically reconfigures advisors at runtime against a proxy created with frozen=true; AOT/native compilation scenarios where configs are frozen; calling Advised methods after the proxy has been built with optimize=true (which often implies frozen).","solutions":["Do not freeze the configuration if runtime advisor mutation is required: call proxyFactory.setFrozen(false) (the default) before getProxy().","Build a new ProxyFactory and create a fresh proxy with the desired advisor set instead of mutating the frozen one.","If you need dynamic advisors, use addAdvice at runtime only on non-frozen proxies or restructure to use a PointcutAdvisor with a dynamic pointcut."],"exampleFix":"// before\nProxyFactory pf = new ProxyFactory(target);\npf.setFrozen(true);\npf.addAdvice(advice);\nObject proxy = pf.getProxy();\n((Advised) proxy).removeAdvisor(0);  // throws\n\n// after\nProxyFactory pf = new ProxyFactory(target);\n// omit setFrozen(true) so the proxy stays mutable\npf.addAdvice(advice);\nObject proxy = pf.getProxy();\n((Advised) proxy).removeAdvisor(0);  // ok","handlingStrategy":"validation","validationCode":"Advised advised = (Advised) proxy;\nif (advised.isFrozen()) {\n  throw new IllegalStateException(\n    \"Cannot remove advisor: proxy config is frozen; rebuild the proxy with frozen=false\");\n}\n((Advised) proxy).removeAdvisor(index);","typeGuard":null,"tryCatchPattern":"try {\n  advised.removeAdvisor(index);\n} catch (AopConfigException ex) {\n  if (ex.getMessage().contains(\"frozen\")) {\n    // rebuild a fresh proxy with the desired advisor set\n  } else throw ex;\n}","preventionTips":["Do not set frozen=true unless you are certain the advisor list will never change.","Cache the original ProxyFactory so you can rebuild the proxy instead of mutating a frozen one.","Prefer removing by Advisor reference (removeAdvisor(advisor)) and guard with isFrozen() first."],"tags":["spring-aop","frozen-config","advisor-mutation","configuration"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}