oracle/graal · info · UnsupportedOperationException
putMember() not supported.
Error message
putMember() not supported.
What it means
UnsupportedOperationException from the read-only ProxyObject exposed by EspressoExternalHostProxies: putMember(key, value) throws because the proxy wraps an immutable Map.copyOf method map — the proxy's members are the host object's methods, not writable properties. Writes through this mirror have no backing store, so the operation is explicitly refused instead of being silently dropped.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalHostProxies.java:386
public void set(long index, Value value) {
throw new UnsupportedOperationException("set() not supported.");
}
@Override
public long getSize() {
return keys.length;
}
};
}
@Override
public boolean hasMember(String key) {
return map.containsKey(key);
}
@Override
public void putMember(String key, Value value) {
throw new UnsupportedOperationException("putMember() not supported.");
}
};
Value computeMethodMapMirror = access.com_oracle_truffle_espresso_vmaccess_guest_GuestHostProxyHandler_computeMethodMap.getMirror();
Value guestClass = guestType.getMetaObject().getMember("class");
return computeMethodMapMirror.execute(guestClass, invocables);
}
private Map<String, ProxyExecutable> computeMethodMap(Class<?> hostClass, EspressoExternalResolvedInstanceType guestType) {
Map<String, ProxyExecutable> map = new HashMap<>();
Set<EspressoExternalResolvedInstanceType> seen = new HashSet<>();
addMethods(hostClass, guestType, map, seen);
return Map.copyOf(map);
}
private void addMethods(Class<?> hostClass, EspressoExternalResolvedInstanceType guestType, Map<String, ProxyExecutable> map, Set<EspressoExternalResolvedInstanceType> seen) {
assert guestType.isInterface();
if (!seen.add(guestType)) {
return;View on GitHub (pinned to a66e9ccd1d)
Solutions
- Use member invocation (call the methods) instead of assignment; the mirror only dispatches methods.
- To expose writable state, add real setter methods to the host class — they appear as invocable members.
- Handle UnsupportedOperationException in the guest interop layer as 'member is not writable' (Truffle also exposes Member.isWritable, which already reports false here).
- Check Member.isWritable(key) before writeMember if the guest runtime supports the interop metadata API.
Example fix
// before (guest JS)
hostProxy.counter = 42; // putMember -> UnsupportedOperationException
// after (host adds a setter; guest calls it)
// host: public void setCounter(int v) { this.counter = v; }
hostProxy.setCounter(42); Defensive patterns
Strategy: validation
Validate before calling
// interop caller: use member metadata before writeMember
if (proxy.getMemberKeys().contains(key) && proxy.getMember(key).isWritable()) {
proxy.putMember(key, value);
} else {
throw new UnsupportedOperationException("member not writable: " + key);
} Try / catch
try { proxy.putMember(key, value); } catch (UnsupportedOperationException e) { /* method-map mirror is read-only: expose a setter method instead */ } Prevention
- Expose setters as methods on the host class instead of expecting property writes on the mirror.
- Query Member.isWritable before writeMember in guest tooling.
- Remember the external host proxy mirrors methods (Map.copyOf), not mutable fields.
When it happens
Trigger: Guest language code executing a property assignment (JS: hostProxy.foo = bar, or interop writeMember) on a host object exposed through the external host proxy mechanism.
Common situations: Guest scripts accustomed to polyglot Value objects that do allow member writes; debuggers/REPLs attempting to set fields on the mirror; mistaking the method-map mirror for a property bag.
Related errors
- set() not supported.
- UnsupportedTypeException serialization is not supported.
- This VM does not support continuations.
- Continuations must be run on the Java on Truffle JVM with th
- This VM does not support continuations.
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/1f153e32d02f73e7.
Report an issue: GitHub.