can1357/oh-my-pi · error

memory:// URL requires a namespace: memory://root

Error message

memory:// URL requires a namespace: memory://root

What it means

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).

Source

Thrown at packages/coding-agent/src/internal-urls/memory-protocol.ts:120

	const firstGlobIndex = rawSegments.findIndex(segment => ["*", "?", "[", "{"].some(char => segment.includes(char)));
	if (firstGlobIndex === -1) {
		throw new Error(`memory:// URL does not contain a glob pattern: ${input}`);
	}

	const rawBasePath = rawSegments.slice(0, firstGlobIndex).join("/") || ".";
	return {
		baseUrl: `memory://${namespace}/${rawBasePath}`,
		globPattern: rawSegments.slice(firstGlobIndex).map(decodeGlobSuffixSegment).join("/"),
	};
}

/**
 * Resolve a memory:// URL to an absolute filesystem path under memory root.
 */
export function resolveMemoryUrlToPath(url: InternalUrl, memoryRoot: string): string {
	const namespace = url.rawHost || url.hostname;
	if (!namespace) {
		throw new Error("memory:// URL requires a namespace: memory://root");
	}
	if (namespace !== MEMORY_NAMESPACE) {
		throw new Error(`Unknown memory namespace: ${namespace}. Supported: ${MEMORY_NAMESPACE}`);
	}

	const rawPathname = url.rawPathname ?? url.pathname;
	const hasPath = rawPathname && rawPathname !== "/" && rawPathname !== "";
	if (!hasPath) {
		return path.resolve(memoryRoot, DEFAULT_MEMORY_FILE);
	}
	let relativePath: string;
	try {
		relativePath = decodeURIComponent(rawPathname.slice(1));
	} catch {
		throw new Error(`Invalid URL encoding in memory:// path: ${url.href}`);
	}

	try {

View on GitHub (pinned to 9690622007)

Solutions

  1. Include the 'root' namespace host in the URL: use memory://root or memory://root/path/to/file.md instead of memory:// or memory:///path.
  2. If the URL is built dynamically, check the namespace variable is non-empty before constructing the URL.
  3. Route through tryResolveInternalUrlSync's error handling and surface the fix to the caller/agent prompt so future reads use memory://root/... form.

Example fix

// before
read("memory:///memory_summary.md")
// after
read("memory://root/memory_summary.md")
Defensive patterns

Strategy: validation

Validate before calling

const url = parseInternalUrl(candidate);
if (!(url.rawHost || url.hostname)) throw new Error(`memory:// URL needs a namespace host: ${candidate}`);

Type guard

function hasNamespace(url: InternalUrl): boolean {
  return Boolean(url.rawHost || url.hostname);
}

Try / catch

try {
  const p = resolveMemoryUrlToPath(url, root);
} catch (err) {
  if (err instanceof Error && err.message.includes("requires a namespace")) {
    // fall back to memory://root default
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/83c7c7f349574619. Report an issue: GitHub.