{"record":{"id":"f0376f8b01179093","repo":"can1357/oh-my-pi","slug":"invalid-url-encoding-in-memory-path-input","errorCode":null,"errorMessage":"Invalid URL encoding in memory:// path: ${input}","messagePattern":"Invalid URL encoding in memory:// path: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/memory-protocol.ts","lineNumber":92,"sourceCode":"\n\t// Parse only the scheme and authority. A literal `?` in the path is glob\n\t// syntax, not a query delimiter, and must survive unchanged.\n\tconst url = parseInternalUrl(urlMatch[1]);\n\tconst namespace = url.rawHost || url.hostname;\n\tif (url.protocol !== \"memory:\" || namespace !== MEMORY_NAMESPACE) {\n\t\tthrow new Error(`Memory glob patterns require the ${MEMORY_NAMESPACE} namespace: ${input}`);\n\t}\n\n\tconst rawPathname = urlMatch[2] ?? \"\";\n\tif (/%(?:2f|5c)/i.test(rawPathname)) {\n\t\tthrow new Error(`Encoded path separators are not allowed in memory:// glob patterns: ${input}`);\n\t}\n\n\tlet relativePath: string;\n\ttry {\n\t\trelativePath = decodeURIComponent(rawPathname.replace(/^\\//, \"\"));\n\t} catch {\n\t\tthrow new Error(`Invalid URL encoding in memory:// path: ${input}`);\n\t}\n\n\ttry {\n\t\tvalidateRelativePath(relativePath);\n\t} catch (error) {\n\t\tthrow toMemoryValidationError(error);\n\t}\n\n\tconst rawSegments = rawPathname.replace(/^\\//, \"\").split(\"/\");\n\tconst firstGlobIndex = rawSegments.findIndex(segment => [\"*\", \"?\", \"[\", \"{\"].some(char => segment.includes(char)));\n\tif (firstGlobIndex === -1) {\n\t\tthrow new Error(`memory:// URL does not contain a glob pattern: ${input}`);\n\t}\n\n\tconst rawBasePath = rawSegments.slice(0, firstGlobIndex).join(\"/\") || \".\";\n\treturn {\n\t\tbaseUrl: `memory://${namespace}/${rawBasePath}`,\n\t\tglobPattern: rawSegments.slice(firstGlobIndex).map(decodeGlobSuffixSegment).join(\"/\"),","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/memory-protocol.ts#L74-L110","documentation":"After stripping the leading slash, the raw pathname is percent-decoded with decodeURIComponent. Malformed escape sequences (e.g. a stray '%' not followed by two hex digits, or truncated multibyte sequences) make decodeURIComponent throw a URIError, which is rethrown with this message naming the original input.","triggerScenarios":"Calling splitMemoryGlobPattern (via memoryGlob) with a memory:// URL whose path contains invalid percent-encoding such as memory://root/notes/50%.md or %zz, or a cut-off escape like %e2%80 at the end.","commonSituations":"Users pasting URLs where a literal '%' (common in file names like '100%_done.md') was never encoded as %25; truncation by a log/UI that clipped the URL; double-encoding pipelines mangling escapes.","solutions":["Encode literal '%' characters in the path as %25 (e.g. 50%25.md) and retry.","Check the full URL for truncated or typo'd escape sequences (%zz, single %, incomplete UTF-8 runs) and repair them.","When building URLs programmatically, always percent-encode with encodeURIComponent rather than concatenating raw strings containing '%'."],"exampleFix":"// before\nsplitMemoryGlobPattern(\"memory://root/reports/50%.md\"); // bare % breaks decode\n// after\nsplitMemoryGlobPattern(\"memory://root/reports/50%25.md\");","handlingStrategy":"validation","validationCode":"function isDecodablePath(rawPathname: string): boolean {\n  try {\n    decodeURIComponent(rawPathname.replace(/^\\//, \"\"));\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return splitMemoryGlobPattern(input);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"Invalid URL encoding in memory:// path\")) {\n    const repaired = input.replace(/%(?![0-9a-f]{2})/gi, \"%25\"); // escape bare %\n    return splitMemoryGlobPattern(repaired);\n  }\n  throw e;\n}","preventionTips":["Encode literal '%' in file names as %25 before building memory:// URLs.","Never truncate URLs in logs/UIs that feed back into reads.","Test round-trips: encode, then decodeURIComponent, to catch malformed escapes early."],"tags":["url-encoding","memory","validation"],"backgroundTag":"invalid-url-encoding","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}