{"record":{"id":"611233d470d5621a","repo":"ruvnet/ruflo","slug":"namespace-contains-invalid-characters-allowed-al","errorCode":null,"errorMessage":"namespace contains invalid characters (allowed: alphanumeric, _, -, ., :)","messagePattern":"namespace contains invalid characters \\(allowed: alphanumeric, _, -, \\., :\\)","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":"The final validateIdentifier check requires the whole namespace to match /^[a-zA-Z0-9_][a-zA-Z0-9_\\-.:]{0,127}$/ — it must start with a letter, digit, or underscore, and contain only alphanumerics, _, -, ., : afterwards. memory_list throws 'namespace contains invalid characters (allowed: alphanumeric, _, -, ., :)' when the namespace survived the shell-meta and traversal checks but still contains an illegal character (space, /, +, unicode) or starts with '-', '.', or ':' (memory-tools.ts:705).","triggerScenarios":"memory_list with namespace 'my patterns' (space), 'team/blue' (slash), 'café' (unicode é), '+prod' or '-prod' or '.cache' (disallowed first character).","commonSituations":"Human-readable namespaces with spaces or slashes; URL- or path-derived namespaces; localized characters; the store/list asymmetry where memory_store accepted the same string because its write-side pattern allows spaces.","solutions":["Use only [A-Za-z0-9_\\-.:] and start with an alphanumeric or _ — e.g. 'my-patterns', 'team:blue'","Slugify: ns.toLowerCase().replace(/[^a-z0-9_\\-.:]+/g, '-').replace(/^[^a-z0-9_]+/, '')","Map '/' hierarchies to ':' which the charset explicitly allows","Add the identical regex test in your caller to fail fast with a localized error message"],"exampleFix":"// before\nawait mcp.callTool('memory_list', { namespace: 'team blue/2026' }); // space and slash -> invalid characters\n\n// after\nawait mcp.callTool('memory_list', { namespace: 'team-blue:2026' });","handlingStrategy":"validation","validationCode":"// Exact mirror of the library's identifier contract.\nconst IDENTIFIER_RE = /^[a-zA-Z0-9_][a-zA-Z0-9_\\-.:]{0,127}$/;\nfunction toValidNamespace(raw: string): string {\n  const slug = raw.replace(/[^A-Za-z0-9_\\-.:]+/g, '-').replace(/^[^A-Za-z0-9_]+/, '');\n  if (!IDENTIFIER_RE.test(slug)) throw new RangeError(`cannot derive a valid namespace from: ${raw}`);\n  return slug;\n}\n// const ns = toValidNamespace(userInput);","typeGuard":"function isValidNamespace(ns: string): ns is string {\n  return /^[a-zA-Z0-9_][a-zA-Z0-9_\\-.:]{0,127}$/.test(ns);\n}","tryCatchPattern":"try {\n  await memoryList({ namespace: ns });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('namespace contains invalid characters')) {\n    // slugify and retry once; if still invalid, reject the input at your boundary\n  }\n  throw e;\n}","preventionTips":["Adopt the exact charset [A-Za-z0-9_-.:] (first char alnum or _) as your namespace policy everywhere","Slugify user-provided namespaces before any memory tool call","Map URL/path hierarchies to ':' separators, not '/' or spaces","Validate namespaces once at config/input load and reuse the validated value"],"tags":["memory","mcp","list","validation","namespace","regex"],"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"}