{"record":{"id":"c385930afd714ebd","repo":"JuliusBrussee/caveman","slug":"tool-search-failed-with-http-response-status","errorCode":null,"errorMessage":"tool search failed with HTTP ${response.status}","messagePattern":"tool search failed with HTTP (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/sdk/typescript/src/index.ts","lineNumber":1605,"sourceCode":"    })),\n    query\n  };\n  if (options?.context !== undefined) body[\"context\"] = options.context;\n  if (options?.maxTools !== undefined) body[\"max_tools\"] = options.maxTools;\n  if (options?.toolSessionId !== undefined) body[\"session_id\"] = options.toolSessionId;\n  // Embedding-similarity is a pure passthrough: the SDK forwards the ranker\n  // choice and the gateway honors \"embeddings\" only when it has an embedding\n  // provider wired. The SDK never computes similarity itself (byte-safe, no\n  // extra deps).\n  if (options?.ranker !== undefined) body[\"ranker\"] = options.ranker;\n\n  const workflow = options?.workflow ?? cave.options.defaultWorkflow ?? \"unlabeled-workflow\";\n  const response = await caveFetch(cave, `${cave.options.baseURL}/sdk/v1/tool-search`, {\n    method: \"POST\",\n    headers: headers(cave, workflow),\n    body: JSON.stringify(body)\n  });\n\tif (!response.ok) throw new Error(`tool search failed with HTTP ${response.status}`);\n  const data = await response.json();\n\n  // Map snake_case response to camelCase\n  const rawSent = strictNonNegativeInt(data.sent_schema_tokens);\n  const rawFull = strictNonNegativeInt(data.full_schema_tokens);\n  const validCounts = rawSent !== null && rawFull !== null && rawSent <= rawFull;\n  const sentSchemaTokens = validCounts ? rawSent : 0;\n  const fullSchemaTokens = validCounts ? rawFull : 0;\n  const savedTokens = fullSchemaTokens - sentSchemaTokens;\n  const reductionPct = fullSchemaTokens === 0 ? 0 : Math.round((savedTokens / fullSchemaTokens) * 1000) / 10;\n\n  const catalogByName = new Map<string, CaveTool>();\n  for (const tool of catalog) {\n    if (typeof tool.name !== \"string\" || tool.name.trim() === \"\" || catalogByName.has(tool.name)) {\n      throw new Error(\"tool catalog names must be non-empty and unique\");\n    }\n    catalogByName.set(tool.name, tool);\n  }","sourceCodeStart":1587,"sourceCodeEnd":1623,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/sdk/typescript/src/index.ts#L1587-L1623","documentation":"Error \"tool search failed with HTTP ${response.status}\" thrown in JuliusBrussee/caveman.","triggerScenarios":"Thrown at packages/sdk/typescript/src/index.ts:1605 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Tool search returned a non-2xx status; check credentials and endpoint, then retry."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}