{"record":{"id":"7821336780d2caae","repo":"can1357/oh-my-pi","slug":"set-host-tools-response-did-not-include-toolnames","errorCode":null,"errorMessage":"set_host_tools response did not include toolNames","messagePattern":"set_host_tools response did not include toolNames","errorType":"exception","errorClass":"RpcError","httpStatus":null,"severity":"error","filePath":"python/omp-rpc/src/omp_rpc/client.py","lineNumber":1109,"sourceCode":"        payload = self._request(\n            \"set_host_tools\",\n            tools=cast(\n                JsonValue,\n                [\n                    {\n                        \"name\": tool.name,\n                        \"label\": tool.label,\n                        \"description\": tool.description,\n                        \"parameters\": tool.parameters,\n                        \"hidden\": tool.hidden,\n                    }\n                    for tool in self._custom_tools\n                ],\n            ),\n        )\n        tool_names = payload.get(\"toolNames\") or []\n        if not isinstance(tool_names, list):\n            raise RpcError(\"set_host_tools response did not include toolNames\")\n        return tuple(str(name) for name in tool_names)\n\n    def set_host_uris(self, host_uris: Sequence[HostUri[Any]]) -> tuple[str, ...]:\n        self._host_uris = tuple(host_uris)\n        if self._process is None:\n            return tuple(uri.scheme for uri in self._host_uris)\n\n        schemes_payload: list[JsonObject] = []\n        for uri in self._host_uris:\n            entry: JsonObject = {\n                \"scheme\": uri.scheme,\n                \"writable\": uri.writable,\n                \"immutable\": uri.immutable,\n            }\n            if uri.description is not None:\n                entry[\"description\"] = uri.description\n            schemes_payload.append(entry)\n","sourceCodeStart":1091,"sourceCodeEnd":1127,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/omp-rpc/src/omp_rpc/client.py#L1091-L1127","documentation":"set_host_tools() registers the host's custom tools with the server and expects the response to echo the accepted tool names in a 'toolNames' list. If payload.get('toolNames') (or an empty-list fallback) is not a list, the client raises this RpcError, since callers rely on the returned tuple of registered tool names.","triggerScenarios":"Server responds to set_host_tools without a toolNames array — older server builds predating the field, servers that reject/ignore custom tool registration, or stub servers returning a bare ack ({} or {\"ok\": true}).","commonSituations":"Client newer than the server (field added in a later protocol revision); custom tool definitions rejected server-side causing an error-shaped payload; mock servers that don't implement set_host_tools.","solutions":["Upgrade the server so set_host_tools echoes toolNames","Check server logs for why the registration failed (schema-invalid tool definitions)","Align client/server versions; the field comes from a specific protocol revision","In tests, make the stub return {\"toolNames\": [...]} matching the requested names"],"exampleFix":"# before: stub acks without the field\nreturn {\"ok\": True}\n\n# after\nreturn {\"toolNames\": [t[\"name\"] for t in received_tools]}","handlingStrategy":"try-catch","validationCode":"# register only serializable, well-formed tool specs\nspecs = [{\"name\": t.name, \"description\": t.description} for t in tools]\nassert all(isinstance(s[\"name\"], str) and s[\"name\"] for s in specs)\n","typeGuard":"def has_tool_names(payload: object) -> bool:\n    names = (payload or {}).get(\"toolNames\") if isinstance(payload, dict) else None\n    return isinstance(names, list)\n","tryCatchPattern":"try:\n    names = client.set_host_tools(tools)\nexcept RpcError as e:\n    if \"did not include toolNames\" in str(e):\n        names = ()  # server too old or rejected registration; log and continue\n    else:\n        raise\n","preventionTips":["Match server version to the client protocol revision that introduced toolNames","Ensure tool specs conform to the expected schema before registration","Make test doubles echo {\"toolNames\": [...]}","Check server logs for registration rejections"],"tags":["rpc","response-validation","host-tools","schema-mismatch"],"backgroundTag":"rpc-response-schema-invalid","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}