JuliusBrussee/caveman · error

cave_memory_value_invalid

cave_memory_value_invalid

Error message

cave_memory_value_invalid

What it means

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.

Solutions

  1. Trim the text and ensure it is 1–8,192 characters before calling; store one concise fact per call.
  2. Split long content into multiple smaller `remember` calls or store it via your own file tool and remember a pointer/summary instead.
  3. If a wrapper invokes the tool, pre-validate length and skip the call for blank text.

Example fix

// before
await memory.cave_memory_remember.execute(id, { text: longDocument }); // > 8192 chars
// after
const summary = summarize(longDocument).slice(0, 8192);
if (summary.trim()) await memory.cave_memory_remember.execute(id, { text: summary });
Defensive patterns

Strategy: validation

Validate before calling

function canRemember(text: unknown): text is string {
  const t = typeof text === "string" ? text.trim() : "";
  return t.length > 0 && t.length <= 8_192;
}
if (!canRemember(args.text)) throw new Error("memory text must be 1-8192 chars");

Type guard

const isMemoryText = (v: unknown): v is string =>
  typeof v === "string" && v.trim().length > 0 && v.trim().length <= 8_192;

Try / catch

try {
  await memory.cave_memory_remember.execute(id, { text });
} catch (e) {
  if ((e as Error).message === "cave_memory_value_invalid") {
    return { remembered: false, reason: "text empty or over 8192 chars" };
  }
  throw e;
}

Prevention

When it happens

Trigger: Model calling `cave_memory_remember` with `{ text: "" }`, whitespace-only text, or a text blob over 8,192 characters.

Common situations: 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.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/395332f111d5e0c3. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/runtime.ts:3166

        if (used + item.entry.text.length > maxChars) continue;
        hits.push(item.entry.text);
        used += item.entry.text.length;
      }
      return {
        content: [{ type: "text", text: JSON.stringify({ hits, basis: "inferred", namespace: definition.namespace }) }],
        details: { namespace: definition.namespace, recallTokensEstimated: Math.ceil(used / 4) },
      };
    },
  };
  const remember: AgentTool<TSchema> = {
    name: "cave_memory_remember",
    label: "cave_memory_remember",
    description: "Remember one explicit fact in declared local namespace.",
    parameters: Type.Object({ text: Type.String() }),
    executionMode: "sequential",
    async execute(_toolCallId, params) {
      const text = (params as { text: string }).text.trim();
      if (text.length === 0 || text.length > 8_192) throw new Error("cave_memory_value_invalid");
      await mutateMemories(filePath, (entries) => {
        const next: MemoryEntry[] = entries.some((entry) => entry.text === text)
          ? entries
          : [...entries, { text, createdAt: Date.now() }];
        return next.length > 1_000 ? next.slice(next.length - 1_000) : next;
      });
      return {
        content: [{ type: "text", text: JSON.stringify({ remembered: true, basis: "inferred" }) }],
        details: { namespace: definition.namespace },
      };
    },
  };
  return [recall, remember];
}

function tokenize(value: string): string[] {
  return value.toLowerCase().match(/[a-z0-9]{2,}/g) ?? [];
}

View on GitHub (pinned to 3ee70a1026)