{"record":{"id":"489eba7c1ce5dad0","repo":"can1357/oh-my-pi","slug":"no-files-matched-pattern","errorCode":null,"errorMessage":"No files matched \"${pattern}\"","messagePattern":"No files matched \"(.+?)\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/compress/index.ts","lineNumber":65,"sourceCode":" * Expand `patterns` into a deduplicated, sorted list of absolute file paths.\n *\n * Entries containing glob metacharacters are matched against `cwd`; everything else is\n * treated as a literal path so filenames containing brackets still resolve. Throws when\n * a literal path is missing or a pattern matches nothing, since silently compressing\n * fewer files than asked is worse than failing.\n */\nexport async function resolveCompressTargets(patterns: readonly string[], cwd: string): Promise<string[]> {\n\tconst found = new Set<string>();\n\tfor (const pattern of patterns) {\n\t\tif (/[*?[\\]{}]/.test(pattern)) {\n\t\t\t// `dot: true` — prompt corpora live under dot directories such as `.omp/commands`.\n\t\t\tconst matches = new Bun.Glob(pattern).scanSync({ cwd, absolute: true, onlyFiles: true, dot: true });\n\t\t\tlet matched = 0;\n\t\t\tfor (const match of matches) {\n\t\t\t\tfound.add(match);\n\t\t\t\tmatched += 1;\n\t\t\t}\n\t\t\tif (matched === 0) throw new Error(`No files matched \"${pattern}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst resolved = path.resolve(cwd, pattern);\n\t\tconst stat = await fs.stat(resolved).catch(() => undefined);\n\t\tif (!stat?.isFile()) throw new Error(`Not a file: ${shortenPath(resolved)}`);\n\t\tfound.add(resolved);\n\t}\n\treturn [...found].sort();\n}\n\n/** Compress every requested file through the rewrite/approve loop. */\nexport async function runCompressCommand(options: CompressCommandOptions): Promise<CompressResult> {\n\tconst maxRounds = options.maxRounds ?? DEFAULT_MAX_ROUNDS;\n\tconst concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;\n\tif (!Number.isInteger(maxRounds) || maxRounds <= 0) throw new Error(\"--rounds must be a positive integer\");\n\tif (!Number.isInteger(concurrency) || concurrency <= 0) throw new Error(\"--agents must be a positive integer\");\n\tif (options.inPlace && options.output) throw new Error(\"--in-place and --out are mutually exclusive\");\n\t// Paths and patterns follow the shell's cwd, as a file-taking CLI must; the project","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/compress/index.ts#L47-L83","documentation":"resolveCompressTargets maps user-supplied file arguments to concrete files. Arguments containing glob metacharacters are scanned with Bun.Glob; if a pattern matches zero files it throws rather than silently compressing nothing. This catches typos and stale patterns early.","triggerScenarios":"Running the compress command with a glob pattern (contains *, ?, [, etc.) that matches no files under cwd — e.g. `src/**/*.ts` in a repo with no src dir, wrong extension, or pattern relative to the wrong directory (cwd is the shell's invocation dir, not the project dir).","commonSituations":"Typo in path or extension (*.tsx vs *.ts); running from a different directory than expected; case-sensitive filesystem mismatch (Readme.MD vs readme.md); files excluded by `dot`/symlink expectations; globbing on Windows paths with backslashes.","solutions":["Run `ls` with the same pattern from your current directory to see what it expands to; fix the pattern.","cd to the directory containing the target files before running the command (patterns resolve against the shell cwd).","Use a direct file path instead of a glob when you know the exact file.","Check file extension/case sensitivity (especially on Linux)."],"exampleFix":"// before\nomp compress 'src/utils/*.ts'   // No files matched\nls src/utils                    // dir actually named src/lib\n// after\nomp compress 'src/lib/*.ts'","handlingStrategy":"validation","validationCode":"import { globSync } from \"node:fs\";\nfunction patternHasMatches(pattern: string, cwd: string): boolean {\n  try { return new Bun.Glob(pattern).scanSync({ cwd, onlyFiles: true, dot: true }).size > 0; }\n  catch { return false; }\n}\n// call before invoking compress with a glob","typeGuard":null,"tryCatchPattern":"try {\n  await runCompressCommand({ files: [pattern] });\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('No files matched')) {\n    process.stderr.write(`${err.message} — check cwd and pattern\\n`);\n  } else throw err;\n}","preventionTips":["Test globs with `ls <pattern>` in the same directory before running compress.","Remember patterns resolve against the shell's cwd, not the project dir.","Watch extension and case sensitivity on Linux (ts vs TS, md vs MD).","Use forward slashes in globs even on Windows."],"tags":["glob","filesystem","cli","input-validation"],"backgroundTag":"no-files-matched-glob","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}