flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableException

can't search values in configuration beans

Error message

can't search values in configuration beans

What it means

containsValue(Object) is unsupported: SpringBeanFactoryProxyMap only resolves beans by name key; reverse lookup of a value would require instantiating/inspecting every bean, so it throws unconditionally.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/SpringBeanFactoryProxyMap.java:65

        return beanFactory.containsBean((String) key);
    }

    @Override
    public Set<Object> keySet() {
        throw new FlowableException("unsupported operation on configuration beans");
        // List<String> beanNames =
        // Arrays.asList(beanFactory.getBeanDefinitionNames());
        // return new HashSet<Object>(beanNames);
    }

    @Override
    public void clear() {
        throw new FlowableException("can't clear configuration beans");
    }

    @Override
    public boolean containsValue(Object value) {
        throw new FlowableException("can't search values in configuration beans");
    }

    @Override
    public Set<Map.Entry<Object, Object>> entrySet() {
        throw new FlowableException("unsupported operation on configuration beans");
    }

    @Override
    public boolean isEmpty() {
        throw new FlowableException("unsupported operation on configuration beans");
    }

    @Override
    public Object put(Object key, Object value) {
        throw new FlowableException("unsupported operation on configuration beans");
    }

    @Override

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Avoid value-based checks; resolve beans by name with get()/containsKey() instead
  2. Compare bean instances from beanFactory.getBean(...) with equals() on your known candidates
  3. Track beans you resolve in your own Map/Collection if you need membership checks on values

Example fix

// before
boolean has = configBeans.containsValue(myBean);
// after
boolean has = configBeans.containsValue(myBean) == false && knownBeans.containsValue(myBean);
// or: track resolved beans yourself
Map<Object,Object> resolved = new HashMap<>();
Object b = configBeans.get("myBean");
if (b != null) resolved.put("myBean", b);
boolean has = resolved.containsValue(myBean);
Defensive patterns

Strategy: type-guard

Validate before calling

if (map instanceof SpringBeanFactoryProxyMap) {
    // do reverse lookup via beanFactory.getBean(...) on known candidates instead
}

Type guard

boolean supportsContainsValue(Map<?,?> m) { return !(m instanceof SpringBeanFactoryProxyMap); }

Try / catch

try {
    found = map.containsValue(bean);
} catch (FlowableException e) {
    found = myResolvedBeans.containsValue(bean);
}

Prevention

When it happens

Trigger: Calling containsValue(value) directly, or indirectly through AbstractMap helpers, Map constructors that validate contents, or framework code performing reverse-lookup checks on the map.

Common situations: Checking whether a bean instance is already present in configuration before registering a replacement, or generic Map-equality/diff utilities run over configuration maps.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/340737d977256794. Report an issue: GitHub.