can1357/oh-my-pi · error

Encoded path separators are not allowed in memory:// glob pa

Error message

Encoded path separators are not allowed in memory:// glob patterns: ${input}

What it means

Percent-encoded '/' (%2F) or backslash (%5C) in the pathname would let a glob suffix smuggle path separators past the segment-based path validation. The library rejects any memory:// glob URL whose raw pathname contains these escapes before decoding, closing a traversal vector.

Source

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

 * cannot escape a safely resolved base directory.
 */
export function splitMemoryGlobPattern(input: string): MemoryGlobPattern {
	const urlMatch = input.match(/^([a-z][a-z0-9+.-]*:\/\/[^/?#]*)(\/.*)?$/i);
	if (!urlMatch) {
		throw new Error(`Invalid memory glob URL: ${input}`);
	}

	// Parse only the scheme and authority. A literal `?` in the path is glob
	// syntax, not a query delimiter, and must survive unchanged.
	const url = parseInternalUrl(urlMatch[1]);
	const namespace = url.rawHost || url.hostname;
	if (url.protocol !== "memory:" || namespace !== MEMORY_NAMESPACE) {
		throw new Error(`Memory glob patterns require the ${MEMORY_NAMESPACE} namespace: ${input}`);
	}

	const rawPathname = urlMatch[2] ?? "";
	if (/%(?:2f|5c)/i.test(rawPathname)) {
		throw new Error(`Encoded path separators are not allowed in memory:// glob patterns: ${input}`);
	}

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

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove the encoded separators: encode each path segment's special characters but leave '/' literal (encodeURIComponent per segment joined by '/').
  2. Decode the offending %2F/%5C into real separators in the URL string before passing it (the literal '/' in the path is allowed).
  3. Sanitize any pipeline that serializes paths into memory:// URLs to skip path-separator escaping.

Example fix

// before
const url = `memory://root/${encodeURIComponent("notes/2024/*.md")}`; // %2F injected
// after
const url = `memory://root/${"notes/2024/*.md".split("/").map(encodeURIComponent).join("/")}`;
Defensive patterns

Strategy: validation

Validate before calling

function hasEncodedSeparators(input: string): boolean {
  return /%(?:2f|5c)/i.test(input);
}
// reject or repair before calling splitMemoryGlobPattern

Type guard

function isSafeMemoryGlobPath(input: string): boolean {
  return !/%(?:2f|5c)/i.test(input);
}

Try / catch

try {
  return splitMemoryGlobPattern(input);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Encoded path separators are not allowed")) {
    throw new Error("Rebuild the memory:// URL encoding per path segment instead of encoding the whole path");
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a memory:// glob URL where the path contains %2f, %2F, %5c, or %5C — typically produced by encodeURIComponent() being applied to a whole path that already contains '/' or '\'.

Common situations: Programmatic URL builders over-encoding paths (encodeURIComponent(path) instead of per-segment encoding); frameworks that double-encode path parameters; LLM-generated URLs that escaped separators.

Related errors


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