{"record":{"id":"395332f111d5e0c3","repo":"JuliusBrussee/caveman","slug":"cave-memory-value-invalid","errorCode":"cave_memory_value_invalid","errorMessage":"cave_memory_value_invalid","messagePattern":"cave_memory_value_invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/runtime.ts","lineNumber":3166,"sourceCode":"        if (used + item.entry.text.length > maxChars) continue;\n        hits.push(item.entry.text);\n        used += item.entry.text.length;\n      }\n      return {\n        content: [{ type: \"text\", text: JSON.stringify({ hits, basis: \"inferred\", namespace: definition.namespace }) }],\n        details: { namespace: definition.namespace, recallTokensEstimated: Math.ceil(used / 4) },\n      };\n    },\n  };\n  const remember: AgentTool<TSchema> = {\n    name: \"cave_memory_remember\",\n    label: \"cave_memory_remember\",\n    description: \"Remember one explicit fact in declared local namespace.\",\n    parameters: Type.Object({ text: Type.String() }),\n    executionMode: \"sequential\",\n    async execute(_toolCallId, params) {\n      const text = (params as { text: string }).text.trim();\n      if (text.length === 0 || text.length > 8_192) throw new Error(\"cave_memory_value_invalid\");\n      await mutateMemories(filePath, (entries) => {\n        const next: MemoryEntry[] = entries.some((entry) => entry.text === text)\n          ? entries\n          : [...entries, { text, createdAt: Date.now() }];\n        return next.length > 1_000 ? next.slice(next.length - 1_000) : next;\n      });\n      return {\n        content: [{ type: \"text\", text: JSON.stringify({ remembered: true, basis: \"inferred\" }) }],\n        details: { namespace: definition.namespace },\n      };\n    },\n  };\n  return [recall, remember];\n}\n\nfunction tokenize(value: string): string[] {\n  return value.toLowerCase().match(/[a-z0-9]{2,}/g) ?? [];\n}","sourceCodeStart":3148,"sourceCodeEnd":3184,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/runtime.ts#L3148-L3184","documentation":"The `cave_memory_remember` tool throws `cave_memory_value_invalid` when the `text` to remember is empty after trimming or longer than 8,192 characters. The local memory store stores only bounded single facts, so out-of-range values are rejected inside the tool's `execute` and surface as a tool-call error.","triggerScenarios":"Model calling `cave_memory_remember` with `{ text: \"\" }`, whitespace-only text, or a text blob over 8,192 characters.","commonSituations":"A model pasting a whole document as a 'fact'; an empty argument from a hallucinated tool call; a caller script forwarding an unset variable as the memory text.","solutions":["Trim the text and ensure it is 1–8,192 characters before calling; store one concise fact per call.","Split long content into multiple smaller `remember` calls or store it via your own file tool and remember a pointer/summary instead.","If a wrapper invokes the tool, pre-validate length and skip the call for blank text."],"exampleFix":"// before\nawait memory.cave_memory_remember.execute(id, { text: longDocument }); // > 8192 chars\n// after\nconst summary = summarize(longDocument).slice(0, 8192);\nif (summary.trim()) await memory.cave_memory_remember.execute(id, { text: summary });","handlingStrategy":"validation","validationCode":"function canRemember(text: unknown): text is string {\n  const t = typeof text === \"string\" ? text.trim() : \"\";\n  return t.length > 0 && t.length <= 8_192;\n}\nif (!canRemember(args.text)) throw new Error(\"memory text must be 1-8192 chars\");","typeGuard":"const isMemoryText = (v: unknown): v is string =>\n  typeof v === \"string\" && v.trim().length > 0 && v.trim().length <= 8_192;","tryCatchPattern":"try {\n  await memory.cave_memory_remember.execute(id, { text });\n} catch (e) {\n  if ((e as Error).message === \"cave_memory_value_invalid\") {\n    return { remembered: false, reason: \"text empty or over 8192 chars\" };\n  }\n  throw e;\n}","preventionTips":["Store one concise fact per call; never pass whole documents.","Truncate/split long text before calling remember.","Skip the call entirely when the trimmed text is empty."],"tags":["memory","validation","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}