{"record":{"id":"7840fe9a0df3a831","repo":"ruvnet/ruflo","slug":"namespace-contains-disallowed-characters-7840fe","errorCode":null,"errorMessage":"namespace contains disallowed characters","messagePattern":"namespace contains disallowed characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/memory-tools.ts","lineNumber":805,"sourceCode":"    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.',\n    category: 'memory',\n    inputSchema: {\n      type: 'object',\n      properties: {\n        namespace: { type: 'string', description: 'Filter by namespace' },\n        limit: { type: 'number', description: 'Maximum results (default: 50)' },\n        offset: { type: 'number', description: 'Offset for pagination (default: 0)' },\n      },\n    },\n    handler: async (input) => {\n      await ensureInitialized();\n      const { listEntries } = await getMemoryFunctions();\n\n      const namespace = input.namespace as string | undefined;\n      const limit = (input.limit as number) || 50;\n      const offset = (input.offset as number) || 0;\n\n      if (namespace) { const vNs = validateIdentifier(namespace, 'namespace'); if (!vNs.valid) throw new Error(vNs.error); }\n\n      try {\n        const result = await listEntries({\n          namespace,\n          limit,\n          offset,\n        });\n\n        const entries = result.entries.map(e => ({\n          key: e.key,\n          namespace: e.namespace,\n          storedAt: e.createdAt,\n          updatedAt: e.updatedAt,\n          accessCount: e.accessCount,\n          hasEmbedding: e.hasEmbedding,\n          size: e.size,\n        }));\n","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/ruvnet/ruflo/blob/9c61c86f06b439af2a95085ae9bb0ca839662e41/v3/@claude-flow/cli/src/mcp-tools/memory-tools.ts#L787-L823","documentation":"validateIdentifier's SHELL_META check (/[;&|`$(){}[\\]<>!#\\\\]/) runs before the traversal and charset checks, so a namespace containing any shell metacharacter fails memory_list with 'namespace contains disallowed characters' (memory-tools.ts:705). It is the #1425 anti-injection guard shared by every MCP tool that accepts an identifier. Characters not in this set (spaces, /, unicode) instead fail the later charset check with the 'invalid characters' message.","triggerScenarios":"memory_list with namespace 'patterns#v2', 'team(a)', 'a|b', 'ns$1', 'dev;prod', or any value containing ; & | ` $ ( ) { } [ ] < > ! # \\ or a NUL byte.","commonSituations":"Punctuation-bearing namespaces produced by templates or shell interpolation; values copied from markdown headings or log lines; the same string having been accepted earlier by memory_store's laxer write-side DANGEROUS_KEY_CHARS check (which permits spaces but also rejects these metacharacters — mismatch messages confuse users).","solutions":["Replace the metacharacters with '_' or '-' in the namespace","Slugify generated namespaces: ns.replace(/[^A-Za-z0-9_\\-.:]+/g, '-')","Check the failing value for the exact set ; & | ` $ ( ) { } [ ] < > ! # \\ and remove those characters","Run the same check in your caller before invoking the tool so errors point at your code with better context"],"exampleFix":"// before\nawait mcp.callTool('memory_list', { namespace: 'patterns#auth(v2)' }); // namespace contains disallowed characters\n\n// after\nawait mcp.callTool('memory_list', { namespace: 'patterns-auth-v2' });","handlingStrategy":"validation","validationCode":"const SHELL_META = /[;&|`$(){}[\\]<>!#\\\\]/;\nfunction stripShellMeta(ns: string): string {\n  return ns.split('').map(c => SHELL_META.test(c) ? '-' : c).join('');\n}\n// const ns = stripShellMeta(rawNs);","typeGuard":"function hasShellMeta(ns: string): boolean {\n  return /[;&|`$(){}[\\]<>!#\\\\]/.test(ns);\n}\n// if (hasShellMeta(ns)) ns = stripShellMeta(ns);","tryCatchPattern":"try {\n  await memoryList({ namespace: ns });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('namespace contains disallowed characters')) {\n    // sanitize the metacharacters (;&|`$(){}[]<>!#\\) and retry once\n  }\n  throw e;\n}","preventionTips":["Build namespaces only from slugified, user-typed-free input","Escape or strip shell metacharacters whenever namespaces originate from templates or shell variables","Apply one canonical namespace policy for store, list, cleanup, and export so all tools agree","Unit-test namespace handling with a string containing every metacharacter"],"tags":["memory","mcp","list","security","validation","namespace"],"backgroundTag":"invalid-identifier-characters","analyzedSha":"9c61c86f06b439af2a95085ae9bb0ca839662e41","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}