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

  1. Check the class name in the exception message; it names the exact unsupported type.
  2. Make custom messages subclass one of the supported base types (DefaultEvent, DefaultTransaction, DefaultMetric, DefaultHeartbeat, DefaultTrace).
  3. Upgrade cat-core so the HTML codec knows any newer built-in message types.
  4. 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

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.