{"record":{"id":"21ade5ba3748d914","repo":"can1357/oh-my-pi","slug":"snippet-file-not-found-resolved","errorCode":null,"errorMessage":"Snippet file not found: ${resolved}","messagePattern":"Snippet file not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/ttsr-cli.ts","lineNumber":156,"sourceCode":"\tastConditions: string[];\n\tastPrefilters: RegExp[];\n\tastRequiresFullScan: boolean;\n}\n\ninterface ScanFileCandidate {\n\tpath: string;\n\tsize?: number;\n}\n\nasync function readSnippet(opts: { snippet?: string; file?: string }): Promise<string> {\n\tif (opts.file) {\n\t\tif (opts.file === STDIN_MARKER) {\n\t\t\treturn await Bun.stdin.text();\n\t\t}\n\t\tconst resolved = path.resolve(opts.file);\n\t\tconst file = Bun.file(resolved);\n\t\tif (!(await file.exists())) {\n\t\t\tthrow new Error(`Snippet file not found: ${resolved}`);\n\t\t}\n\t\treturn await file.text();\n\t}\n\tif (opts.snippet !== undefined) return opts.snippet;\n\tif (process.stdin.isTTY === false) return await Bun.stdin.text();\n\tthrow new Error(\"No snippet provided. Pass inline text, --file <path>, or pipe via --file -.\");\n}\n\nfunction previewSnippet(text: string): string {\n\tconst single = text.replace(/\\s+/g, \" \").trim();\n\treturn single.length > 80 ? `${single.slice(0, 77)}…` : single;\n}\n\nfunction deriveLang(filePaths: string[] | undefined): string | undefined {\n\tfor (const filePath of filePaths ?? []) {\n\t\tconst ext = path.extname(filePath.replaceAll(\"\\\\\", \"/\"));\n\t\tif (ext.length > 1) return ext.slice(1).toLowerCase();\n\t}","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/ttsr-cli.ts#L138-L174","documentation":"`omp ttsr test` reads the snippet from `--file <path>`. readSnippet resolves the path and checks existence with Bun.file before reading; if the resolved path does not exist it throws this error naming the absolute path. It prevents a silent empty-snippet test run.","triggerScenarios":"Running `omp ttsr test --file <path> ...` where the path does not exist (typo, wrong working directory, deleted/moved file, or a path that only exists relative to a different cwd). Also when `--file` is anything other than `-` (stdin marker).","commonSituations":"Relative path typo from the wrong directory; pointing --file at a directory instead of a file; shell variable expanding to empty (e.g. `--file $SNIPPET` with SNIPPET unset); testing a rule against a file that was renamed in the repo.","solutions":["Check the path printed in the error and fix the typo or run from the correct directory.","Verify the file exists: `ls -l <path>` or `test -f <path>` before invoking.","If you meant stdin, pass `--file -` (or omit --file and pipe input).","If the file was moved, update the path or regenerate the snippet file first."],"exampleFix":"// before\nomp ttsr test --file snipets/login.ts --rule rules/no-secrets.md\n// after\nomp ttsr test --file snippets/login.ts --rule rules/no-secrets.md","handlingStrategy":"validation","validationCode":"import * as fs from \"node:fs\";\nconst resolved = path.resolve(opts.file);\nif (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile()) {\n  throw new Error(`Snippet file does not exist or is not a file: ${resolved}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await snippet(args);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Snippet file not found:\")) {\n    console.error(`Check --file path (cwd=${process.cwd()}): ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Use absolute paths in scripts instead of cwd-relative ones.","Quote shell variables and guard against empty expansion: \"${SNIPPET_FILE:?unset}\".","Verify with `test -f \"$FILE\"` before invoking the CLI.","Use `--file -` with a pipe when the content comes from another command."],"tags":["cli","file-not-found","path","validation"],"backgroundTag":"file-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}