{"record":{"id":"99115bb81548a3fc","repo":"can1357/oh-my-pi","slug":"memory-url-does-not-contain-a-glob-pattern-i","errorCode":null,"errorMessage":"memory:// URL does not contain a glob pattern: ${input}","messagePattern":"memory:// URL does not contain a glob pattern: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/memory-protocol.ts","lineNumber":104,"sourceCode":"\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(\"/\"),\n\t};\n}\n\n/**\n * Resolve a memory:// URL to an absolute filesystem path under memory root.\n */\nexport function resolveMemoryUrlToPath(url: InternalUrl, memoryRoot: string): string {\n\tconst namespace = url.rawHost || url.hostname;\n\tif (!namespace) {\n\t\tthrow new Error(\"memory:// URL requires a namespace: memory://root\");\n\t}\n\tif (namespace !== MEMORY_NAMESPACE) {","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/memory-protocol.ts#L86-L122","documentation":"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.","triggerScenarios":"Calling memoryGlob/splitMemoryGlobPattern with a fully literal memory:// path such as memory://root/notes/summary.md — no wildcard anywhere in the segments.","commonSituations":"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.","solutions":["If you want one file, drop the glob API and read the plain memory://root/path/file.md URL directly.","If you intended a pattern, add the wildcard: e.g. memory://root/notes/*.md.","Verify upstream encoding didn't escape your metacharacters (\\*, \\?) into literals — unescape them in the URL string before calling."],"exampleFix":"// before\nconst p = splitMemoryGlobPattern(\"memory://root/notes/summary.md\"); // no wildcard\n// after — plain read for a literal path\nconst res = await readInternalUrl(\"memory://root/notes/summary.md\");\n// or, if a pattern was intended:\nconst p = splitMemoryGlobPattern(\"memory://root/notes/*.md\");","handlingStrategy":"validation","validationCode":"const GLOB_CHARS = /[*?[{]/;\nfunction containsGlobMeta(memoryUrl: string): boolean {\n  const path = memoryUrl.replace(/^memory:\\/\\/[^/]+/, \"\");\n  return path.split(\"/\").some(seg => GLOB_CHARS.test(seg));\n}\n// use glob API only when containsGlobMeta(input), else read directly","typeGuard":"function isGlobUrl(input: string): boolean {\n  return /memory:\\/\\/.*[*?[{]/.test(input);\n}","tryCatchPattern":"try {\n  return await memoryGlob(input);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"memory:// URL does not contain a glob pattern\")) {\n    return readInternalUrl(input); // literal path — plain read instead\n  }\n  throw e;\n}","preventionTips":["Route literal memory:// paths to the plain read API; reserve glob APIs for wildcard patterns.","Ensure wildcards survive encoding — do not escape *, ?, [, { unless they are meant as literals.","Check that variables intended to hold patterns actually contain metacharacters before calling."],"tags":["memory","glob","validation"],"backgroundTag":"missing-glob-pattern","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}