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
- Remove the encoded separators: encode each path segment's special characters but leave '/' literal (encodeURIComponent per segment joined by '/').
- Decode the offending %2F/%5C into real separators in the URL string before passing it (the literal '/' in the path is allowed).
- 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
- encodeURIComponent each path segment and join with literal '/', never encode whole paths.
- Scan generated memory:// URLs for %2F/%5C in CI or at config load time.
- Avoid frameworks/options that double-encode path parameters.
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
- Destination paths cannot contain parent traversal or NUL byt
- Shared-folder destination escapes its configured root
- Refusing to download outside the workspace: ${downloadPath}
- Absolute paths are not allowed in ${scheme}:// URLs: ${rawPa
- Path traversal (..) is not allowed in ${scheme}:// URLs: ${r
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/0195f09ed7b8c993.
Report an issue: GitHub.