ToolNotFoundError in the source throws two messages, and whether there is a colon and a second clause separates them:
| Message | Meaning | Where to look |
|---|---|---|
unknown tool "<name>" | The name is registered nowhere | Whether the gateway renamed or truncated tools, or an intermediary rewrote the call |
unknown tool "<name>": <reachableFrom> | The name is visible but the presentation layer forbids calling it directly | Not the gateway.Check DSH_TOOLS_MODE and the preset's tool-presentation |
The second shape is the one that gets misdiagnosed
Its typical setting is PTC mode: the model may only call run_code directly, so other native names are visible but rejected on direct call, with a note on where to call them from. This has nothing to do with a gateway, yet the text reads like a protocol error and the instinct is to go check the gateway.
Locating it in one pass
- Read the second clause. If there is
: …, take the presentation branch and stop looking at the gateway. - Without the clause, capture one outbound request and compare each
tools[].function.nameagainst the locally registered names. - Identical names plus UNKNOWN_TOOL means a local problem; differing names mean a gateway or intermediary rewrote them.