{"record":{"id":"6e3453425c9fd0c2","repo":"flowable/flowable-engine","slug":"unsupported-operation-on-configuration-beans","errorCode":null,"errorMessage":"unsupported operation on configuration beans","messagePattern":"unsupported operation on configuration beans","errorType":"exception","errorClass":"org.flowable.common.engine.api.FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/SpringBeanFactoryProxyMap.java","lineNumber":52,"sourceCode":"    @Override\n    public Object get(Object key) {\n        if ((key == null) || !String.class.isAssignableFrom(key.getClass())) {\n            return null;\n        }\n        return beanFactory.getBean((String) key);\n    }\n\n    @Override\n    public boolean containsKey(Object key) {\n        if ((key == null) || !String.class.isAssignableFrom(key.getClass())) {\n            return false;\n        }\n        return beanFactory.containsBean((String) key);\n    }\n\n    @Override\n    public Set<Object> keySet() {\n        throw new FlowableException(\"unsupported operation on configuration beans\");\n        // List<String> beanNames =\n        // Arrays.asList(beanFactory.getBeanDefinitionNames());\n        // return new HashSet<Object>(beanNames);\n    }\n\n    @Override\n    public void clear() {\n        throw new FlowableException(\"can't clear configuration beans\");\n    }\n\n    @Override\n    public boolean containsValue(Object value) {\n        throw new FlowableException(\"can't search values in configuration beans\");\n    }\n\n    @Override\n    public Set<Map.Entry<Object, Object>> entrySet() {\n        throw new FlowableException(\"unsupported operation on configuration beans\");","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/SpringBeanFactoryProxyMap.java#L34-L70","documentation":"SpringBeanFactoryProxyMap is a read-only Map facade over a Spring BeanFactory that resolves beans lazily via get(Object). Only lookups (get, containsKey) are supported; keySet() intentionally throws because bean names cannot be exposed as modifiable Map keys. This is a deliberate guard, not a bug.","triggerScenarios":"Any code path that calls keySet() on a SpringBeanFactoryProxyMap instance, e.g. iterating map keys, copying the map into another Map via a constructor that reads keySet/entrySet, or framework code that introspects the Map.","commonSituations":"Passing the proxy map to utilities that copy or serialize Maps (new HashMap<>(map), MapUtils, Jackson/JSON serialization), debugging code that dumps map contents, or custom code iterating beans to find a candidate bean.","solutions":["Do not iterate the map; look up beans directly with map.get(beanName) or beanFactory.getBean(beanName)","Use beanFactory.getBeanDefinitionNames() on the underlying ListableBeanFactory to enumerate bean names instead","Copy only resolved entries: iterate your known bean names and call get() on each, building your own Map","If you need a full Map, replace SpringBeanFactoryProxyMap with a concrete map populated from getBeanDefinitionNames()"],"exampleFix":"// before\nfor (Object beanName : springBeanFactoryProxyMap.keySet()) { ... }\n// after\nfor (String beanName : listableBeanFactory.getBeanDefinitionNames()) {\n    Object bean = springBeanFactoryProxyMap.get(beanName);\n}","handlingStrategy":"type-guard","validationCode":"if (map instanceof SpringBeanFactoryProxyMap) {\n    // use beanFactory.getBeanDefinitionNames() instead of keySet()\n}","typeGuard":"boolean isReadOnlyBeanMap(Map<?,?> m) { return m instanceof SpringBeanFactoryProxyMap; }","tryCatchPattern":"try {\n    keys = map.keySet();\n} catch (FlowableException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"unsupported operation\")) {\n        keys = new HashSet<>(Arrays.asList(listableBeanFactory.getBeanDefinitionNames()));\n    } else { throw e; }\n}","preventionTips":["Treat SpringBeanFactoryProxyMap as lookup-only: call get()/containsKey(), never bulk views","Enumerate beans via ListableBeanFactory.getBeanDefinitionNames(), not the map","Check documentation/Javadoc of Map facades before passing them to copy/serialize utilities"],"tags":["spring","map","unsupported-operation","flowable"],"backgroundTag":"unsupported-operation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}