{"record":{"id":"fb64a0cadb6cac91","repo":"pentaho/pentaho-kettle","slug":"unexpected-error-trying-to-encode-object","errorCode":null,"errorMessage":"Unexpected error trying to encode object.","messagePattern":"Unexpected error trying to encode object\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"engine-ext/api/src/main/java/org/pentaho/di/engine/api/remote/MessageEncoder.java","lineNumber":47,"sourceCode":" * Created by ccaspanello on 7/20/17.\n */\npublic class MessageEncoder implements Encoder.Text<Message> {\n  /**\n   * Encode the given AEL Message object into a String.\n   *\n   * @param object the Message object being encoded.\n   * @return the encoded object as a string.\n   */\n  @Override\n  public String encode( Message object ) throws EncodeException {\n    try {\n      ByteArrayOutputStream baos = new ByteArrayOutputStream();\n      ObjectOutputStream oos = new ObjectOutputStream( baos );\n      oos.writeObject( object );\n      oos.close();\n      return EncodeUtil.encodeBase64Zipped( baos.toByteArray() );\n    } catch ( Exception e ) {\n      throw new RuntimeException( \"Unexpected error trying to encode object.\", e );\n    }\n  }\n\n  @Override\n  public void init( EndpointConfig config ) {\n    // Do Nothing\n  }\n\n  @Override\n  public void destroy() {\n    // Do Nothing\n  }\n}\n","sourceCodeStart":29,"sourceCodeEnd":61,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine-ext/api/src/main/java/org/pentaho/di/engine/api/remote/MessageEncoder.java#L29-L61","documentation":"MessageEncoder.encode serializes a Message to bytes via ObjectOutputStream, then Base64+GZIP encodes it for WebSocket transmission. Any failure during serialization or encoding is wrapped in this RuntimeException because the WebSocket Encoder interface only allows RuntimeException.","triggerScenarios":"Calling encode(Message) with an object whose field graph contains non-Serializable members; the object or a nested field's class changed without updating serialVersionUID causing serialization errors; NotSerializableException on a nested type.","commonSituations":"Adding a new field holding a non-Serializable type (e.g. an InputStream, Logger, or lambda) to a Message class; passing a Message subclass with transient-unsupported state; incompatible class changes after upgrade.","solutions":["Inspect the wrapped cause: NotSerializableException names the offending class — make it Serializable or mark the field transient.","Review recent changes to Message classes for non-Serializable fields and fix them.","Keep serialVersionUID stable when evolving Message classes to avoid InvalidClassException.","Test encoding of every Message subtype in a unit test before shipping."],"exampleFix":"// before\npublic class MyMessage implements Message {\n  private InputStream data; // NotSerializableException\n}\n// after\npublic class MyMessage implements Message {\n  private transient InputStream data;\n  private byte[] dataBytes; // serializable representation\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight check that all nested values are serializable\nfor (Object v : messageValues) {\n  if (!(v instanceof Serializable)) throw new IllegalArgumentException(\"Non-serializable field: \" + v.getClass());\n}","typeGuard":null,"tryCatchPattern":"try {\n  String encoded = encoder.encode(message);\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof NotSerializableException nse) {\n    logger.error(\"Make this Serializable or transient: \" + nse.getMessage());\n  }\n  throw e;\n}","preventionTips":["Only put Serializable types in Message fields; mark volatile resources transient.","Add a unit test that encodes and decodes every Message subtype.","Keep serialVersionUID fixed when evolving Message classes."],"tags":["serialization","websocket","notserializable"],"backgroundTag":"json-marshal-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}