dianping/cat · error · RuntimeException
Unsupported message type: %s.
Error message
Unsupported message type: %s.
What it means
HtmlMessageCodec.encodeMessage walks the message tree rendering HTML and throws RuntimeException("Unsupported message type: <class>.") when a message is none of Transaction/Event/Trace/Metric/Heartbeat (and not the special RemoteLink event type). It means a custom or newer Message implementation reached the HTML renderer, which only knows the built-in types.
Source
Thrown at cat-core/src/main/java/com/dianping/cat/message/codec/HtmlMessageCodec.java:251
}
} else if (message instanceof Event) {
String type = message.getType();
if ("RemoteCall".equals(type)) {
return encodeLogViewLink(tree, message, buf, level, counter);
} else if ("RemoteLink".equals(type)) {
return encodeRemoteLink(tree, message, buf, level, counter);
} else {
return encodeLine(tree, message, buf, 'E', Policy.DEFAULT, level, counter);
}
} else if (message instanceof Trace) {
return encodeLine(tree, message, buf, 'L', Policy.DEFAULT, level, counter);
} else if (message instanceof Metric) {
return encodeLine(tree, message, buf, 'M', Policy.DEFAULT, level, counter);
} else if (message instanceof Heartbeat) {
return encodeLine(tree, message, buf, 'H', Policy.DEFAULT, level, counter);
} else {
throw new RuntimeException(String.format("Unsupported message type: %s.", message.getClass()));
}
}
protected int encodeRemoteLink(MessageTree tree, Message message, ByteBuf buf, int level, LineCounter counter) {
BufferHelper helper = m_bufferHelper;
int count = 0;
if (counter != null) {
counter.inc();
count += helper.tr1(buf, "link");
} else {
count += helper.tr1(buf, null);
}
String link = message.getData().toString();
String name = message.getName();
View on GitHub (pinned to e815e74d4c)
Solutions
- Check the class name in the exception message; it names the exact unsupported type.
- Make custom messages subclass one of the supported base types (DefaultEvent, DefaultTransaction, DefaultMetric, DefaultHeartbeat, DefaultTrace).
- Upgrade cat-core so the HTML codec knows any newer built-in message types.
- Filter unknown message types out of the tree before HTML rendering if they cannot be represented.
Example fix
// before
class MyMessage implements Message { ... } // encoded -> throws
// after
class MyMessage extends DefaultEvent { ... } // renders as event line 'E' Defensive patterns
Strategy: type-guard
Type guard
static String htmlKind(Message m) {
if (m instanceof Transaction) return "t";
if (m instanceof Event || m instanceof Trace || m instanceof Metric || m instanceof Heartbeat) return "ok";
return null; // unsupported
} Try / catch
catch (RuntimeException e) { if (e.getMessage().startsWith("Unsupported message type")) renderFallback(tree); else throw e; } Prevention
- Subclass Default* message types for custom data instead of implementing Message.
- Version-check both ends before enabling new message kinds.
When it happens
Trigger: Encoding a MessageTree that contains a user class implementing Message directly (instead of extending DefaultEvent/DefaultTransaction etc.), or a message type added in a newer CAT version being rendered by an older HtmlMessageCodec.
Common situations: Custom message implementations injected by plugins; mixing CAT client/server versions so new message kinds hit an old HTML view; test fixtures with mock Message objects that are not subclasses of the known types.
Related errors
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/d0713a596c559fcd.
Report an issue: GitHub.