{"record":{"id":"549dc1c116c7479d","repo":"NationalSecurityAgency/ghidra","slug":"protocol-error-invalid-value-kinds","errorCode":null,"errorMessage":"Protocol error: Invalid value kinds","messagePattern":"Protocol error: Invalid value kinds","errorType":"exception","errorClass":"TraceRmiError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java","lineNumber":1132,"sourceCode":"\t\t}\n\t\telse {\n\t\t\tobject.remove(lifespan);\n\t\t}\n\t\treturn ReplyRemoveObject.getDefaultInstance();\n\t}\n\n\tprotected ReplyRetainValues handleRetainValues(RequestRetainValues req) {\n\t\t// This is not a primitive DB operation, but should be more efficient server side.\n\t\tTraceObject object = requireOpenTrace(req.getOid()).getObject(req.getObject(), false);\n\t\tif (object == null) {\n\t\t\treturn ReplyRetainValues.getDefaultInstance();\n\t\t}\n\t\tLifespan span = toLifespan(req.getSpan());\n\t\tCollection<? extends TraceObjectValue> values = switch (req.getKinds()) {\n\t\t\tcase VK_ELEMENTS -> object.getElements(span);\n\t\t\tcase VK_ATTRIBUTES -> object.getAttributes(span);\n\t\t\tcase VK_BOTH -> object.getValues(span);\n\t\t\tdefault -> throw new TraceRmiError(\"Protocol error: Invalid value kinds\");\n\t\t};\n\t\tSet<String> keysToKeep = Set.copyOf(req.getKeysList());\n\t\tList<String> keysToDelete = values.stream()\n\t\t\t\t.map(v -> v.getEntryKey())\n\t\t\t\t.filter(k -> !keysToKeep.contains(k))\n\t\t\t\t.distinct()\n\t\t\t\t.toList();\n\t\tfor (String key : keysToDelete) {\n\t\t\tobject.setValue(span, key, null, ConflictResolution.TRUNCATE);\n\t\t}\n\t\treturn ReplyRetainValues.getDefaultInstance();\n\t}\n\n\tprotected ReplySaveTrace handleSaveTrace(RequestSaveTrace req)\n\t\t\tthrows CancelledException, IOException {\n\t\tOpenTrace open = requireOpenTrace(req.getOid());\n\t\ttry (CloseableTaskMonitor monitor = plugin.createMonitor()) {\n\t\t\topen.trace.save(\"TraceRMI\", monitor);","sourceCodeStart":1114,"sourceCodeEnd":1150,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java#L1114-L1150","documentation":"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.","triggerScenarios":"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.","commonSituations":"Mixing a newer TraceRmi client (or py-ghidra/ghidratrace) with an older Ghidra frontend; using an unreleased feature flag the server lacks.","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."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"RequestRetainValues.ValueKinds k = req.getKinds();\nif (k != VK_ELEMENTS && k != VK_ATTRIBUTES && k != VK_BOTH) {\n    throw new IllegalStateException(\"unsupported value kinds: \" + k);\n}","typeGuard":"boolean supportedKinds(RequestRetainValues.ValueKinds k) {\n    return k == VK_ELEMENTS || k == VK_ATTRIBUTES || k == VK_BOTH;\n}","tryCatchPattern":"try {\n    handler.retainValues(req);\n} catch (TraceRmiError e) {\n    // unsupported enum -> version mismatch; align client/server versions\n}","preventionTips":["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."],"tags":["trace-rmi","protocol","version-mismatch","retain-values"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}