ruvnet/ruflo · error
namespace exceeds 128 characters
Error message
namespace exceeds 128 characters
What it means
validateIdentifier caps identifiers at 128 characters; memory_list throws this variant when a longer namespace string is supplied (memory-tools.ts:705). The cap is part of the shared identifier contract used by dozens of MCP tools (agent IDs, session IDs, worker IDs) to keep storage keys and shell-facing strings bounded. Notably, the write-side validateMemoryInput has no namespace length cap — you can store under a 200-character namespace but then be unable to list it by that namespace.
Solutions
- Shorten the namespace to 128 characters or fewer, restricted to alphanumerics, _, -, ., :
- Derive a compact slug or hash for machine-generated long namespaces
- Move descriptive detail into keys or tags, not the namespace
- If entries were already written under a long namespace, re-store them under a short one (then clean up the old entries) so list/cleanup/export work
Example fix
// before
const ns = `team-alpha/experiments/${fullDescription}`; // 141 chars
await mcp.callTool('memory_list', { namespace: ns }); // namespace exceeds 128 characters
// after
const ns = 'team-alpha:exp-2026q2'; // compact, valid identifier
await mcp.callTool('memory_list', { namespace: ns }); Defensive patterns
Strategy: validation
Validate before calling
const IDENTIFIER_RE = /^[a-zA-Z0-9_][a-zA-Z0-9_\-.:]{0,127}$/;
function assertListableNamespace(ns: string): void {
if (ns.length > 128) throw new RangeError(`namespace too long (${ns.length} > 128)`);
if (!IDENTIFIER_RE.test(ns)) throw new RangeError('namespace must match [A-Za-z0-9_-.:] and start alnum/_');
}
// assertListableNamespace(ns); await mcp.callTool('memory_list', { namespace: ns }); Type guard
function isListableNamespace(ns: string): boolean {
return /^[a-zA-Z0-9_][a-zA-Z0-9_\-.:]{0,127}$/.test(ns);
} Try / catch
try {
await memoryList({ namespace: ns });
} catch (e) {
if (e instanceof Error && e.message.includes('namespace exceeds 128 characters')) {
// deterministic: shorten/slug the namespace, never retry the long form
}
throw e;
} Prevention
- Cap generated namespaces at well under 128 characters (e.g. 64) to leave headroom
- Remember the write path has no namespace length cap — enforce the 128 limit in your own write path to keep store/list consistent
- Put long descriptors in keys or tags, not namespaces
- Include a namespace-format lint in CI for config-driven namespace values
When it happens
Trigger: memory_list with a namespace assembled from a long path, a sentence, or concatenated tags that exceeds 128 characters, e.g. 'team-alpha/experiments/2026/q2/long-descriptor-name-continued...'.
Common situations: Auto-generated namespaces that embed file paths or descriptions; hitting the store/list asymmetry after a migration or script change; copying a long memory key into the namespace field.
Related errors
- namespace contains disallowed characters
- namespace contains invalid characters (allowed…
- Key exceeds maximum length of
- Namespace contains disallowed characters
- namespace contains path traversal
AI-assisted analysis of ruvnet/ruflo@9c61c86f06 (2026-08-18).
Data as JSON: /api/errors/4681aa0c944152fc.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/mcp-tools/memory-tools.ts:805
description: 'Enumerate stored memory entries (optionally filtered by namespace/tags) without semantic search. Use when native Glob is wrong because the entries are not files (they live in .swarm/memory.db). For inspection / audit / "what is in my memory" — pair with memory_search for retrieval-by-meaning.',
category: 'memory',
inputSchema: {
type: 'object',
properties: {
namespace: { type: 'string', description: 'Filter by namespace' },
limit: { type: 'number', description: 'Maximum results (default: 50)' },
offset: { type: 'number', description: 'Offset for pagination (default: 0)' },
},
},
handler: async (input) => {
await ensureInitialized();
const { listEntries } = await getMemoryFunctions();
const namespace = input.namespace as string | undefined;
const limit = (input.limit as number) || 50;
const offset = (input.offset as number) || 0;
if (namespace) { const vNs = validateIdentifier(namespace, 'namespace'); if (!vNs.valid) throw new Error(vNs.error); }
try {
const result = await listEntries({
namespace,
limit,
offset,
});
const entries = result.entries.map(e => ({
key: e.key,
namespace: e.namespace,
storedAt: e.createdAt,
updatedAt: e.updatedAt,
accessCount: e.accessCount,
hasEmbedding: e.hasEmbedding,
size: e.size,
}));
View on GitHub (pinned to 9c61c86f06)