oracle/graal · info · UnsupportedOperationException

set() not supported.

Error message

set() not supported.

What it means

UnsupportedOperationException from the read-only ProxyArray that EspressoExternalHostProxies.getMemberKeys builds over the host object's member-key map. The array is a derived view (keys of an immutable Map.copyOf map of methods); mutating it has no meaningful semantics — writes would not propagate back to the host class — so set() deliberately throws.

Source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalHostProxies.java:369

                return map.get(key);
            }

            @Override
            public Object getMemberKeys() {
                Object[] keys = map.keySet().toArray();
                return new ProxyArray() {
                    @Override
                    public Object get(long index) {
                        try {
                            return keys[Math.toIntExact(index)];
                        } catch (ArithmeticException e) {
                            throw new ArrayIndexOutOfBoundsException("Index should be an int");
                        }
                    }

                    @Override
                    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.");
            }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Do not write to the member-keys view; it reflects the host object's method set, which is fixed by the class.
  2. If guest code needs a mutable array, copy the keys into a guest-native array first (e.g. JS [...keys]).
  3. Catch/handle UnsupportedOperationException in the guest interop layer and surface 'read-only' to the script author.
  4. Verify you are not confusing getMemberKeys() (read-only metadata) with an actual data array returned by a member call.

Example fix

// before (guest JS)
hostObj.memberKeys[0] = 'x'; // UnsupportedOperationException

// after (guest JS)
const keys = [...hostObj.memberKeys]; // copy into guest array
keys[0] = 'x'; // mutation on the copy only
Defensive patterns

Strategy: validation

Validate before calling

// interop caller: check writability metadata before write
if (memberKeys.isMemberWritable() /* or Member.isWritable for arrays */) {
    memberKeys.setElement(idx, v);
} else {
    throw new UnsupportedOperationException("member keys are a read-only view");
}

Try / catch

try { arr.set(idx, value); } catch (UnsupportedOperationException e) { /* read-only key view: copy into guest array instead */ }

Prevention

When it happens

Trigger: Guest language code calling the array 'put/store' operation (e.g. JS arr[0] = x) on the member-keys mirror obtained from a host object exposed via the external host proxy.

Common situations: Guest scripts treating every interop array as mutable; generic polyglot tooling (REPLs, debuggers) that attempts writes during exploration; copying guest code from a mutable Java array mirror to a host object's key view.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/2ef55aaeb4be7160. Report an issue: GitHub.