{"record":{"id":"e2d5436eab8e2ab3","repo":"spring-projects/spring-framework","slug":"advisor-index-is-out-of-bounds-this-configurat","errorCode":null,"errorMessage":"Advisor index {} is out of bounds: This configuration only has {} advisors.","messagePattern":"Advisor index (.+?) is out of bounds: This configuration only has (.+?) advisors\\.","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java","lineNumber":333,"sourceCode":"\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\n\tpublic int indexOf(Advisor advisor) {\n\t\tAssert.notNull(advisor, \"Advisor must not be null\");\n\t\treturn this.advisors.indexOf(advisor);","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java#L315-L351","documentation":"removeAdvisor(int index) (line 332) validates the index against the advisor list size. It throws when index is negative or greater than size-1, telling you exactly how many advisors exist. This runs after the frozen check, so it only matters on a non-frozen configuration.","triggerScenarios":"Calling removeAdvisor with an index < 0 or >= advisors.size(); computing an index dynamically (e.g. via indexOf returning -1 and not checking) and passing it through.","commonSituations":"Using indexOf(advisor) which returned -1 (not found) and blindly passing it to removeAdvisor; stale index from a previous snapshot; off-by-one when iterating.","solutions":["Guard with: int i = advised.indexOf(a); if (i >= 0) advised.removeAdvisor(i);","Call getAdvisorCount()/getAdvisors().length first and bounds-check your index","Prefer removeAdvisor(advisor) over manual index arithmetic, then check its boolean return"],"exampleFix":"// before\nint i = advised.indexOf(someAdvisor);  // could be -1\nadvised.removeAdvisor(i);\n\n// after\nif (!advised.removeAdvisor(someAdvisor)) {\n  // advisor was not present; handle gracefully\n}","handlingStrategy":"validation","validationCode":"int count = advised.getAdvisorCount();\nif (index < 0 || index > count - 1) {\n  throw new IndexOutOfBoundsException(\"advisor index \" + index + \" out of bounds (size \" + count + \")\");\n}\nadvised.removeAdvisor(index);","typeGuard":"private static boolean validAdvisorIndex(AdvisedSupport a, int i) {\n  return a != null && i >= 0 && i < a.getAdvisorCount();\n}","tryCatchPattern":null,"preventionTips":["Prefer removeAdvisor(advisor) and check its boolean result over index arithmetic","Always recompute the index from getAdvisorCount() immediately before removal"],"tags":["spring-aop","advised","advisor","index-out-of-bounds"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}