JuliusBrussee/caveman · error · Error
caveman agent: invalid memory namespace ${JSON.stringify(opt
Error message
caveman agent: invalid memory namespace ${JSON.stringify(options.namespace)} What it means
Thrown by the memory() builder when options.namespace fails ^[a-z0-9][a-z0-9_-]{0,95}$: namespaces must start with a lowercase letter or digit, continue with lowercase letters, digits, underscore or hyphen, and be at most 96 characters. The strictness exists because the namespace becomes a store key / identifier, so uppercase, spaces, dots, slashes and unicode are refused at construction.
Source
Thrown at packages/agent/src/primitives.ts:269
if (!match) throw new Error("cave_memory_ttl_invalid");
const amount = Number(match[1]);
const scale = match[2] === "m" ? 60_000 : match[2] === "h" ? 3_600_000 : 86_400_000;
const milliseconds = amount * scale;
if (!Number.isSafeInteger(amount) || !Number.isSafeInteger(milliseconds) || milliseconds <= 0) {
throw new Error("cave_memory_ttl_invalid");
}
return milliseconds;
}
export function memory(options: {
namespace: string;
provenance?: MemoryDefinition["provenance"];
ttl: string;
recallBudget: number;
consent?: MemoryDefinition["consent"];
}): MemoryDefinition {
if (!/^[a-z0-9][a-z0-9_-]{0,95}$/.test(options.namespace)) {
throw new Error(`caveman agent: invalid memory namespace ${JSON.stringify(options.namespace)}`);
}
if (!Number.isSafeInteger(options.recallBudget) || options.recallBudget < 0) {
throw new Error("caveman agent: memory recallBudget must be a non-negative integer");
}
try {
memoryTTLMilliseconds(options.ttl);
} catch {
throw new Error("caveman agent: memory ttl must use positive m, h, or d duration");
}
// Fail closed at CONSTRUCTION, not at tool-call time: the durable
// store implements only local, single-tenant memory. A `project`/`external`
// provenance or a `project_shared` consent is a shared-backend contract this
// package does not provide, so it is refused here rather than burning a model
// turn to discover a config the framework already knew was unsupported.
const provenance = options.provenance ?? "local";
if (provenance !== "local") {
throw new Error("cave_memory_provenance_unsupported: only \"local\" memory is supported");
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Slugify the namespace before calling memory(): lowercase, trim, replace runs of non-[a-z0-9_-] with '-', and truncate to 96 chars
- Pick a short stable identifier by hand, e.g. 'session-notes' or 'repo-context'
- Validate user-supplied namespaces with the same regex before agent construction so the error is attributed to the input, not the builder
Example fix
// before
memory({ namespace: 'Team Notes/2026', ttl: '7d', recallBudget: 10 });
// after
memory({ namespace: 'team-notes-2026', ttl: '7d', recallBudget: 10 }); Defensive patterns
Strategy: validation
Validate before calling
const NS_RE = /^[a-z0-9][a-z0-9_-]{0,95}$/;
function normalizeNamespace(raw: string): string {
const slug = raw.toLowerCase().trim().replace(/[^a-z0-9_-]+/g, '-').replace(/^-+/, '').slice(0, 96);
if (!NS_RE.test(slug)) throw new Error(`cannot derive namespace from '${raw}'`);
return slug;
} Type guard
function isMemoryNamespace(value: unknown): value is string { return typeof value === 'string' && /^[a-z0-9][a-z0-9_-]{0,95}$/.test(value); } Try / catch
try { memory({ namespace, ttl, recallBudget }); } catch (e) { if (e instanceof Error && e.message.startsWith('caveman agent: invalid memory namespace')) throw new ConfigError('namespace must be lowercase slug (<=96 chars)', { cause: e }); throw e; } Prevention
- Always slugify user/path-derived names before using them as namespaces
- Keep namespaces short constants defined next to the memory definition
- Test the slug helper with unicode, slashes and spaces
When it happens
Trigger: Calling memory({ namespace: ... }) with values like 'My Notes', 'user/notes', 'ns.v2', 'über-memory', '' (empty), a 97+ character string, or a name starting with '-' or '_'.
Common situations: Deriving the namespace from a file path, project name, or free-form user input (e.g. 'My App Memory' or 'org/team/notes') instead of a slug; renaming a product and reusing the display name as the namespace.
Related errors
- cave_memory_ttl_invalid
- caveman agent: memory recallBudget must be a non-negative in
- caveman agent: memory ttl must use positive m, h, or d durat
- cave_budget_denomination_ambiguous
- cave_budget_max_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/75c30aefd6d4ad56.
Report an issue: GitHub.