{"record":{"id":"752bf4c08c1ee7d9","repo":"paperclipai/paperclip","slug":"tool-not-found","errorCode":"tool_not_found","errorMessage":"Tool \"${toolName}\" not found","messagePattern":"Tool \"(.+?)\" not found","errorType":"http","errorClass":"ToolGatewayHttpError","httpStatus":404,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":2596,"sourceCode":"        upstreamToolName: input.tool.upstreamToolName ?? input.tool.name,\n        riskLevel: input.tool.risk,\n        arguments: input.parameters ?? {},\n        idempotencyKey: input.idempotencyKey ?? null,\n        sideEffecting: input.tool.risk !== \"read\",\n      },\n      consumeRateLimit: input.consumeRateLimit === true,\n    };\n  }\n\n  function policyErrorStatus(decision: ToolAccessDecision) {\n    if (decision.decision === \"rate_limited\") return 429;\n    return 403;\n  }\n\n  function findStaticTool(toolName: string): ToolGatewayDescriptor {\n    const tool = allTools().find((candidate) => candidate.name === toolName);\n    if (!tool) {\n      throw new ToolGatewayHttpError(\n        404,\n        `Tool \"${toolName}\" not found`,\n        \"tool_not_found\",\n        { tool: toolName },\n      );\n    }\n    return tool;\n  }\n\n  async function findToolForSession(\n    session: ToolGatewaySession,\n    toolName: string,\n  ): Promise<ToolGatewayDescriptor> {\n    const connectedTools = await connectedMcpToolsForCompany(session.companyId);\n    const hasOnDemandTargets = connectedTools.some(isOnDemandRemoteTool);\n    const virtualTools = hasOnDemandTargets ? VIRTUAL_TOOLS : [];\n    const tool = [...allTools(), ...connectedTools, ...virtualTools]\n      .filter(","sourceCodeStart":2578,"sourceCodeEnd":2614,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/tool-gateway.ts#L2578-L2614","documentation":"Catalog lookup miss: the requested tool name (static tool, connected MCP tool, or virtual on-demand tool) is not present for this company/session, so no descriptor can be resolved and the call is rejected before any policy evaluation. Usually caused by a disconnected app, a renamed upstream tool, or calling a virtual tool when no on-demand targets exist.","triggerScenarios":"Thrown at server/src/services/tool-gateway.ts:1865 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the tool name against the list of available tools for this session; it may be misspelled or the providing plugin/connection is down."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}