{"record":{"id":"808d81e4f8375a4a","repo":"rohitg00/agentmemory","slug":"observe-failed-for-obs-toolname-res-status","errorCode":null,"errorMessage":"observe failed for ${obs.toolName}: ${res.status} ${res.statusText}${body ? ` — ${body.slice(0, 160)}` : \"\"}","messagePattern":"observe failed for (.+?): (.+?) (.+?)(.+?)` : \"\"\\}","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/cli.ts","lineNumber":2889,"sourceCode":"    };\n\n    try {\n      const res = await fetch(url, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify(payload),\n        signal: AbortSignal.timeout(5000),\n      });\n      if (res.ok) {\n        stored++;\n      } else {\n        const body = await res.text().catch(() => \"\");\n        p.log.warn(\n          `observe failed for ${obs.toolName}: ${res.status} ${res.statusText}${body ? ` — ${body.slice(0, 160)}` : \"\"}`,\n        );\n      }\n    } catch (err) {\n      p.log.warn(\n        `observe request failed for ${obs.toolName}: ${err instanceof Error ? err.message : String(err)}`,\n      );\n    }\n  }\n\n  await postJsonStrict(`${base}/agentmemory/session/end`, { sessionId: session.id });\n  return stored;\n}\n\nasync function runDemoSearch(base: string, query: string): Promise<SearchResult> {\n  const data = await postJson<{ results?: Array<{ title?: string }> }>(\n    `${base}/agentmemory/smart-search`,\n    { query, limit: 5 },\n    10000,\n  );\n  const items = data?.results ?? [];\n  return {\n    query,","sourceCodeStart":2871,"sourceCodeEnd":2907,"githubUrl":"https://github.com/rohitg00/agentmemory/blob/e04ba88819c365c9acf9d6661ea802143e728bd6/src/cli.ts#L2871-L2907","documentation":"The CLI's observe flow POSTs tool observations to the daemon's REST API; when the response status is not ok, it logs 'observe failed for <toolName>: <status> <statusText> — <body excerpt>' via p.log.warn. The daemon answered, but rejected or errored on the observation (e.g. 400 bad payload, 401 bad secret, 404 wrong route/version mismatch). Non-fatal: the session continues and only session/end uses strict POST.","triggerScenarios":"A POST of a tool observation returns res.ok === false, typically 401 (wrong AGENTMEMORY_SECRET), 400 (payload fails REST field validation/whitelisting), or 404 (daemon version without the observe route).","commonSituations":"CLI and daemon version mismatch after an upgrade; mismatched AGENTMEMORY_SECRET between CLI and daemon; a proxy between them returning an error page body (which appears truncated in the message).","solutions":["Read the status/body in the message: fix auth for 401 (align AGENTMEMORY_SECRET) or the payload for 400.","Update the CLI to match the daemon version (npm update agentmemory) so the observe endpoint exists.","Check the daemon is the real agentmemory server, not another service answering on that port (an HTML body hints at a proxy).","Retry manually with curl -H \"Authorization: Bearer $AGENTMEMORY_SECRET\" to the observe endpoint to see the full error."],"exampleFix":"// before: stale secret on CLI\n// observe failed for Bash: 401 Unauthorized\n// after\nexport AGENTMEMORY_SECRET=$(cat ~/.agentmemory/secret)","handlingStrategy":"try-catch","validationCode":"const res = await fetch(`${base}/agentmemory/session/observe`, {\n  method: \"POST\",\n  headers: { Authorization: `Bearer ${secret}`, \"Content-Type\": \"application/json\" },\n  body: JSON.stringify(obs),\n});\nif (!res.ok) console.warn(`pre-check failed: ${res.status} ${await res.text()}`);","typeGuard":null,"tryCatchPattern":"try {\n  const res = await postObservation(obs);\n  if (!res.ok) {\n    const body = await res.text().catch(() => \"\");\n    console.warn(`observe failed: ${res.status} ${body.slice(0,160)}`);\n    if (res.status === 401) fixSecret();\n  }\n} catch (err) { /* network error — observation dropped, non-fatal */ }","preventionTips":["Keep CLI and daemon versions aligned; upgrade both together.","Verify AGENTMEMORY_SECRET matches between CLI and daemon.","Check daemon logs for the rejecting request to see the server-side reason.","Remember observe failures are non-fatal by design; only session/end is strict."],"tags":["http","rest-api","observability","cli","non-fatal"],"backgroundTag":"http-request-rejected","analyzedSha":"e04ba88819c365c9acf9d6661ea802143e728bd6","analyzedAt":"2026-08-30T01:07:40.754Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}