can1357/oh-my-pi · error

memory:// URL does not contain a glob pattern: ${input}

Error message

memory:// URL does not contain a glob pattern: ${input}

What it means

splitMemoryGlobPattern exists to split a memory:// URL into a literal base directory plus a glob suffix. If no path segment contains any of the glob metacharacters *, ?, [, or {, there is nothing to split — the library throws instead of returning a degenerate pattern, steering the caller to a plain memory:// read.

Source

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

	}

	let relativePath: string;
	try {
		relativePath = decodeURIComponent(rawPathname.replace(/^\//, ""));
	} catch {
		throw new Error(`Invalid URL encoding in memory:// path: ${input}`);
	}

	try {
		validateRelativePath(relativePath);
	} catch (error) {
		throw toMemoryValidationError(error);
	}

	const rawSegments = rawPathname.replace(/^\//, "").split("/");
	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) {

View on GitHub (pinned to 9690622007)

Solutions

  1. If you want one file, drop the glob API and read the plain memory://root/path/file.md URL directly.
  2. If you intended a pattern, add the wildcard: e.g. memory://root/notes/*.md.
  3. Verify upstream encoding didn't escape your metacharacters (\*, \?) into literals — unescape them in the URL string before calling.

Example fix

// before
const p = splitMemoryGlobPattern("memory://root/notes/summary.md"); // no wildcard
// after — plain read for a literal path
const res = await readInternalUrl("memory://root/notes/summary.md");
// or, if a pattern was intended:
const p = splitMemoryGlobPattern("memory://root/notes/*.md");
Defensive patterns

Strategy: validation

Validate before calling

const GLOB_CHARS = /[*?[{]/;
function containsGlobMeta(memoryUrl: string): boolean {
  const path = memoryUrl.replace(/^memory:\/\/[^/]+/, "");
  return path.split("/").some(seg => GLOB_CHARS.test(seg));
}
// use glob API only when containsGlobMeta(input), else read directly

Type guard

function isGlobUrl(input: string): boolean {
  return /memory:\/\/.*[*?[{]/.test(input);
}

Try / catch

try {
  return await memoryGlob(input);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("memory:// URL does not contain a glob pattern")) {
    return readInternalUrl(input); // literal path — plain read instead
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling memoryGlob/splitMemoryGlobPattern with a fully literal memory:// path such as memory://root/notes/summary.md — no wildcard anywhere in the segments.

Common situations: Config or agent output routing a single-file read through the glob API; wildcards lost because they were percent-escaped into literals by an earlier encoding step (decodeGlobSuffixSegment un-escapes \* to \[*\] style literals); a variable that was expected to hold a pattern but contains a plain path.

Related errors


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