{"record":{"id":"68b52ffaad1e74cb","repo":"can1357/oh-my-pi","slug":"memory-url-requires-a-namespace-memory-root-68b52f","errorCode":null,"errorMessage":"memory:// URL requires a namespace: memory://root or memory://<memory-id>","messagePattern":"memory:// URL requires a namespace: memory://root or memory://<memory-id>","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/memory-protocol.ts","lineNumber":299,"sourceCode":"\n/**\n * Protocol handler for memory:// URLs.\n * Resolves file-backed roots against the calling session cwd when provided.\n * Contextless callers fall back to the live-session registry for legacy\n * cross-session lookups.\n */\nexport class MemoryProtocolHandler implements ProtocolHandler {\n\treadonly scheme = \"memory\";\n\treadonly immutable = true;\n\n\tasync resolve(url: InternalUrl, context?: ResolveContext): Promise<InternalResource> {\n\t\tconst backend = memoryBackendFromContext(context);\n\t\tif (backend === \"off\") {\n\t\t\tthrow new Error(\"Unknown protocol: memory://\");\n\t\t}\n\t\tconst namespace = url.rawHost || url.hostname;\n\t\tif (!namespace) {\n\t\t\tthrow new Error(\"memory:// URL requires a namespace: memory://root or memory://<memory-id>\");\n\t\t}\n\n\t\t// Mnemopi rows live in SQLite banks per session, keyed by memory id.\n\t\t// Any host other than the file-backed `root` namespace is treated as a\n\t\t// mnemopi memory id lookup. This is the read counterpart to\n\t\t// `memory_edit update` and lets agents inspect the full content of a\n\t\t// clipped recall preview before overwriting it (issue #4443).\n\t\tif (namespace !== MEMORY_NAMESPACE) {\n\t\t\tconst mnemopiStates = mnemopiSessionStatesFromRegistry();\n\t\t\tconst hindsightActive =\n\t\t\t\tbackend === \"hindsight\" ||\n\t\t\t\t(mnemopiStates.length === 0 &&\n\t\t\t\t\tAgentRegistry.global()\n\t\t\t\t\t\t.list()\n\t\t\t\t\t\t.some(ref => ref.session?.getHindsightSessionState?.()));\n\t\t\tif (hindsightActive) {\n\t\t\t\t// Hindsight keeps memories server-side and exposes no\n\t\t\t\t// `memory://<id>` addressing, yet the shared `recall` tool","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/memory-protocol.ts#L281-L317","documentation":"With a memory backend active, the host portion of a memory:// URL is the namespace: 'root' for the file-backed memory summary, or a mnemopi memory id. A URL with no host at all (e.g. 'memory://' or 'memory:///path') has nothing to resolve, so resolve throws and tells the caller the two accepted URL forms.","triggerScenarios":"Calling MemoryProtocolHandler.resolve with an InternalUrl whose rawHost/hostname are empty — 'memory://', 'memory:///' — from a read tool call or programmatic URL construction that omitted the namespace.","commonSituations":"Agents emitting 'read memory://' after truncation; template strings where the id variable was empty; users typing memory:// in a path prompt without the 'root' host.","solutions":["Read the project memory summary with 'memory://root'.","Read a stored mnemopi memory by id with 'memory://<memory-id>' using an id listed by recall.","Fix the URL builder/prompt so the namespace is always interpolated and non-empty."],"exampleFix":"// before\nread(\"memory://\")\n// after\nread(\"memory://root\")","handlingStrategy":"validation","validationCode":"const ns = url.rawHost || url.hostname;\nif (!ns) throw new Error(`Use memory://root or memory://<memory-id>, got: ${url.href}`);","typeGuard":"function hasNamespace(url: InternalUrl): boolean {\n  return Boolean(url.rawHost || url.hostname);\n}","tryCatchPattern":"try {\n  return await handler.resolve(url, ctx);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"requires a namespace\")) {\n    return await handler.resolve(parseInternalUrl(\"memory://root\"), ctx);\n  }\n  throw err;\n}","preventionTips":["Always include a host: memory://root for the summary, memory://<id> for mnemopi rows.","Validate interpolated id variables are non-empty before building the URL.","Surface valid forms to agents via the handler's completion output."],"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"}