oracle/graal · error · NotSerializableException
UnsupportedTypeException serialization is not supported.
Error message
UnsupportedTypeException serialization is not supported.
What it means
UnsupportedTypeException (thrown by Truffle interop when guest values do not match a parameter/accessor type) deliberately blocks Java serialization. Its private writeObject always throws NotSerializableException because the exception carries polyglot value references that cannot be faithfully serialized. Attempting to write such an exception through ObjectOutputStream triggers this failure.
Source
Thrown at espresso/src/com.oracle.truffle.espresso.polyglot/src/com/oracle/truffle/espresso/polyglot/UnsupportedTypeException.java:118
* supported.
* <p>
* In addition a cause may be provided. The cause should only be set if the guest language code
* caused this problem. An example for this is a language specific proxy mechanism that invokes
* guest language code to describe an object. If the guest language code fails to execute and
* this interop exception is a valid interpretation of the error, then the error should be
* provided as cause.
*
* @param cause the guest language exception that caused the error.
*
* @since 21.0
*/
public static UnsupportedTypeException create(Object[] suppliedValues, String hint, Throwable cause) {
return new UnsupportedTypeException(hint, suppliedValues, cause);
}
@SuppressWarnings({"static-method", "unused"})
private void writeObject(ObjectOutputStream outputStream) throws IOException {
throw new NotSerializableException(UnsupportedTypeException.class.getSimpleName() + " serialization is not supported.");
}
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Do not serialize the exception itself; extract and serialize the message string and class name instead.
- Before serializing a Throwable chain, walk getCause()/getSuppressed() and replace any UnsupportedTypeException with a plain RuntimeException carrying its message.
- If using a framework with pluggable serializers, switch that message type to a string-based serializer.
- Log the full exception locally (toString includes the offending values) and ship only the log record.
Example fix
// before
objectOutputStream.writeObject(caughtException); // may contain UnsupportedTypeException
// after
Throwable safe = caughtException;
if (safe instanceof UnsupportedTypeException ute) {
safe = new RuntimeException(ute.getClass().getName() + ": " + ute.getMessage());
}
objectOutputStream.writeObject(safe); Defensive patterns
Strategy: try-catch
Try / catch
try {
out.writeObject(throwable);
} catch (NotSerializableException e) {
out.writeObject(sanitize(throwable)); // replace UnsupportedTypeException in the chain with a plain RuntimeException
} Prevention
- Never serialize polyglot exceptions; log them locally and ship strings.
- Walk Throwable chains for polyglot types before any writeObject call.
- Configure distributed frameworks to serialize exception metadata (class + message), not the exception object.
When it happens
Trigger: Calling ObjectOutputStream.writeObject on an UnsupportedTypeException (or on a Throwable graph containing one, e.g. serializing a request-scoped exception to a remote node or into a session). Also triggered by frameworks that auto-serialize exceptions (RMI, Spring session, akka serialization, distributed test runners).
Common situations: Polyglot/Espresso apps that propagate interop type errors across process boundaries; saving exceptions to disk for later inspection; sending exceptions over a message queue. Works locally, fails only when the exception crosses a serialization boundary.
Related errors
- Espresso cannot evaluate Java sources directly, only a few s
- invalid interface type mapping specified: {}
- Missing expected guest type conversion interface in polyglot
- Class not found for polyglot type conversion handler: {}
- ConversionHandler does not implement the polyglot type conve
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/adbb47afcbf0b254.
Report an issue: GitHub.