{"record":{"id":"83c7c7f349574619","repo":"can1357/oh-my-pi","slug":"memory-url-requires-a-namespace-memory-root","errorCode":null,"errorMessage":"memory:// URL requires a namespace: memory://root","messagePattern":"memory:// URL requires a namespace: memory://root","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/memory-protocol.ts","lineNumber":120,"sourceCode":"\tconst firstGlobIndex = rawSegments.findIndex(segment => [\"*\", \"?\", \"[\", \"{\"].some(char => segment.includes(char)));\n\tif (firstGlobIndex === -1) {\n\t\tthrow new Error(`memory:// URL does not contain a glob pattern: ${input}`);\n\t}\n\n\tconst rawBasePath = rawSegments.slice(0, firstGlobIndex).join(\"/\") || \".\";\n\treturn {\n\t\tbaseUrl: `memory://${namespace}/${rawBasePath}`,\n\t\tglobPattern: rawSegments.slice(firstGlobIndex).map(decodeGlobSuffixSegment).join(\"/\"),\n\t};\n}\n\n/**\n * Resolve a memory:// URL to an absolute filesystem path under memory root.\n */\nexport function resolveMemoryUrlToPath(url: InternalUrl, memoryRoot: string): string {\n\tconst namespace = url.rawHost || url.hostname;\n\tif (!namespace) {\n\t\tthrow new Error(\"memory:// URL requires a namespace: memory://root\");\n\t}\n\tif (namespace !== MEMORY_NAMESPACE) {\n\t\tthrow new Error(`Unknown memory namespace: ${namespace}. Supported: ${MEMORY_NAMESPACE}`);\n\t}\n\n\tconst rawPathname = url.rawPathname ?? url.pathname;\n\tconst hasPath = rawPathname && rawPathname !== \"/\" && rawPathname !== \"\";\n\tif (!hasPath) {\n\t\treturn path.resolve(memoryRoot, DEFAULT_MEMORY_FILE);\n\t}\n\tlet relativePath: string;\n\ttry {\n\t\trelativePath = decodeURIComponent(rawPathname.slice(1));\n\t} catch {\n\t\tthrow new Error(`Invalid URL encoding in memory:// path: ${url.href}`);\n\t}\n\n\ttry {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/memory-protocol.ts#L102-L138","documentation":"resolveMemoryUrlToPath parses memory:// URLs into filesystem paths under the project's memory root. The URL host is the namespace; only the file-backed 'root' namespace is supported by this sync resolver. It throws when the URL has no host (e.g. 'memory://root' was passed as a bare string with no authority, or the URL was 'memory:///path' with an empty host).","triggerScenarios":"Calling resolveMemoryUrlToPath with an InternalUrl whose rawHost/hostname are empty — e.g. parsing 'memory://' or 'memory:///notes.md' where the namespace was omitted, or constructing the URL programmatically without setting the host.","commonSituations":"Hand-written tool calls like `read memory://` missing the 'root' host; templated URL builders that interpolate an empty namespace variable; code that copied the path-only form 'memory:///file.md' assuming the default namespace is implicit.","solutions":["Include the 'root' namespace host in the URL: use memory://root or memory://root/path/to/file.md instead of memory:// or memory:///path.","If the URL is built dynamically, check the namespace variable is non-empty before constructing the URL.","Route through tryResolveInternalUrlSync's error handling and surface the fix to the caller/agent prompt so future reads use memory://root/... form."],"exampleFix":"// before\nread(\"memory:///memory_summary.md\")\n// after\nread(\"memory://root/memory_summary.md\")","handlingStrategy":"validation","validationCode":"const url = parseInternalUrl(candidate);\nif (!(url.rawHost || url.hostname)) throw new Error(`memory:// URL needs a namespace host: ${candidate}`);","typeGuard":"function hasNamespace(url: InternalUrl): boolean {\n  return Boolean(url.rawHost || url.hostname);\n}","tryCatchPattern":"try {\n  const p = resolveMemoryUrlToPath(url, root);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"requires a namespace\")) {\n    // fall back to memory://root default\n  } else throw err;\n}","preventionTips":["Always write memory://root[/path], never bare memory:// or memory:///path.","Validate the namespace is non-empty when interpolating URLs from variables.","Use completion (handler.complete) to pick valid memory:// forms."],"tags":["url","memory-protocol","validation"],"backgroundTag":"missing-url-namespace","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}