{"record":{"id":"5ebb4f3d25e61496","repo":"santifer/career-ops","slug":"not-a-regular-file","errorCode":null,"errorMessage":"not a regular file","messagePattern":"not a regular file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"verify-ats.mjs","lineNumber":851,"sourceCode":"    }\n\n    const helpRequested = args.includes('--help') || args.includes('-h');\n    if (!targetArg || helpRequested) {\n      console.log(`Usage: node verify-ats.mjs <generated-cv.html> [--keywords \"a,b,c\"] [--role \"...\"] [--min-score N] [--json]\n\nScores a generated CV's HTML for ATS parseability (0-100 + letter grade) and lists\nconcrete, fixable issues. Deterministic, read-only. Exits 0 when score >= --min-score\n(default ${DEFAULT_MIN_SCORE}) and no critical issue is present, else 1.\n\nKeyword coverage (--keywords / --role) is advisory and never changes the score.`);\n      // An explicit --help is a success; a missing target is a usage error.\n      process.exit(helpRequested ? 0 : 1);\n    }\n\n    const targetPath = isAbsolute(targetArg) ? targetArg : join(process.cwd(), targetArg);\n    let html;\n    try {\n      if (!statSync(targetPath).isFile()) throw new Error('not a regular file');\n      html = readFileSync(targetPath, 'utf-8');\n    } catch (err) {\n      console.error(`ERROR: cannot read target file: ${targetArg} (${err.code || err.message})`);\n      process.exit(1);\n    }\n    const result = auditAts(html, { keywords, role });\n    const pass = isPass(result, minScore);\n    const file = basename(targetPath);\n\n    if (asJson) {\n      console.log(JSON.stringify({ file, pass, minScore, ...result }, null, 2));\n    } else {\n      printHuman(result, file, minScore);\n    }\n    // Set exitCode (don't process.exit) so buffered stdout drains before exit.\n    process.exitCode = pass ? 0 : 1;\n  }\n}","sourceCodeStart":833,"sourceCodeEnd":869,"githubUrl":"https://github.com/santifer/career-ops/blob/e7abd431fce9348a95261acac9e0c14779c35df8/verify-ats.mjs#L833-L869","documentation":"verify-ats.mjs checks that its target argument is a regular file via statSync(targetPath).isFile() and throws 'not a regular file' when the stat succeeds but points at a directory, symlink to a directory, FIFO, device, etc. The throw is inside a try block and surfaces to the user as 'ERROR: cannot read target file: ... (not a regular file)'.","triggerScenarios":"Running the ATS audit against a directory (e.g. `node verify-ats.mjs output/` or `.`), or against a special file, instead of an exported CV HTML file.","commonSituations":"Passing a directory of generated CVs instead of one file; a broken/symlinked path resolving to a non-file; forgetting the filename at the end of a path; glob not expanded by the shell.","solutions":["Pass the path to a single HTML file, not a directory: node verify-ats.mjs output/cv-001.html","Check what the path points at: stat <path>","If auditing a directory, loop over files instead of passing the directory itself","Remove or replace broken symlinks pointing at non-files"],"exampleFix":"// before\n$ node verify-ats.mjs output/\n// after\n$ node verify-ats.mjs output/cv-tailored.html","handlingStrategy":"validation","validationCode":"import { statSync } from 'node:fs';\nconst st = statSync(targetPath);\nif (!st.isFile()) {\n  console.error(`${targetPath} is not a regular file`);\n  process.exit(1);\n}","typeGuard":"const isRegularFile = (p) => { try { return statSync(p).isFile(); } catch { return false; } };","tryCatchPattern":"try {\n  const html = readFileSync(targetPath, 'utf-8');\n} catch (err) {\n  console.error(`cannot read ${targetPath}: ${err.code || err.message}`);\n  process.exit(1);\n}","preventionTips":["Pass explicit file paths, never directories, to file-based CLIs","Quote paths and verify shell globs expanded to exactly one file","Use tab-completion in the shell to avoid truncated or directory paths","Check `stat <path>` when unsure what a path points to"],"tags":["file","cli","ats"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"e7abd431fce9348a95261acac9e0c14779c35df8","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}