NationalSecurityAgency/ghidra · error · TraceRmiError
Protocol error: Invalid value kinds
Error message
Protocol error: Invalid value kinds
What it means
Thrown by TraceRmiHandler.handleRetainValues when the RequestRetainValues.getKinds() enum value is not one of VK_ELEMENTS, VK_ATTRIBUTES, or VK_BOTH — i.e. the switch falls to default. This indicates the client sent a value-kinds enum ordinal the server does not recognize, which is a protocol/semver mismatch: a newer client is using an enum value unknown to this server.
Source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java:1132
}
else {
object.remove(lifespan);
}
return ReplyRemoveObject.getDefaultInstance();
}
protected ReplyRetainValues handleRetainValues(RequestRetainValues req) {
// This is not a primitive DB operation, but should be more efficient server side.
TraceObject object = requireOpenTrace(req.getOid()).getObject(req.getObject(), false);
if (object == null) {
return ReplyRetainValues.getDefaultInstance();
}
Lifespan span = toLifespan(req.getSpan());
Collection<? extends TraceObjectValue> values = switch (req.getKinds()) {
case VK_ELEMENTS -> object.getElements(span);
case VK_ATTRIBUTES -> object.getAttributes(span);
case VK_BOTH -> object.getValues(span);
default -> throw new TraceRmiError("Protocol error: Invalid value kinds");
};
Set<String> keysToKeep = Set.copyOf(req.getKeysList());
List<String> keysToDelete = values.stream()
.map(v -> v.getEntryKey())
.filter(k -> !keysToKeep.contains(k))
.distinct()
.toList();
for (String key : keysToDelete) {
object.setValue(span, key, null, ConflictResolution.TRUNCATE);
}
return ReplyRetainValues.getDefaultInstance();
}
protected ReplySaveTrace handleSaveTrace(RequestSaveTrace req)
throws CancelledException, IOException {
OpenTrace open = requireOpenTrace(req.getOid());
try (CloseableTaskMonitor monitor = plugin.createMonitor()) {
open.trace.save("TraceRMI", monitor);View on GitHub (pinned to d5f144c24d)
Solutions
- Align client and server to the same Ghidra/TraceRmi version.
- Downgrade the client feature usage to only VK_ELEMENTS/VK_ATTRIBUTES/VK_BOTH until the server is upgraded.
- Rebuild the client against the protobuf definitions matching the deployed server.
Defensive patterns
Strategy: type-guard
Validate before calling
RequestRetainValues.ValueKinds k = req.getKinds();
if (k != VK_ELEMENTS && k != VK_ATTRIBUTES && k != VK_BOTH) {
throw new IllegalStateException("unsupported value kinds: " + k);
} Type guard
boolean supportedKinds(RequestRetainValues.ValueKinds k) {
return k == VK_ELEMENTS || k == VK_ATTRIBUTES || k == VK_BOTH;
} Try / catch
try {
handler.retainValues(req);
} catch (TraceRmiError e) {
// unsupported enum -> version mismatch; align client/server versions
} Prevention
- Keep the TraceRmi client and server on the same Ghidra version.
- Rebuild client stubs against the protobuf schema the deployed server uses.
- Restrict usage to the documented VK_* constants.
When it happens
Trigger: Client and server are built from different protobuf schema versions where ValueKinds gained a new variant; the client serializes an unrecognized enum ordinal; a corrupted message yields an invalid enum.
Common situations: Mixing a newer TraceRmi client (or py-ghidra/ghidratrace) with an older Ghidra frontend; using an unreleased feature flag the server lacks.
Related errors
- Cannot send TraceRmi message with excessive length
- Cannot receive TraceRmi message with excessive message lengt
- Unknown query tag: {mainName}
- Usage: ghidra trace retain-values [OPTIONS] PATH [KEYS...]
- Invalid argument: {key_list[0]}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/549dc1c116c7479d.
Report an issue: GitHub.