{"record":{"id":"d0fb45844eb075d5","repo":"remoteintech/remote-jobs","slug":"usage-node-validate-companies-js-file1-md-file","errorCode":null,"errorMessage":"Usage: node validate-companies.js <file1.md> [file2.md ...]","messagePattern":"Usage: node validate-companies\\.js <file1\\.md> \\[file2\\.md \\.\\.\\.\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":".github/scripts/validate-companies.js","lineNumber":210,"sourceCode":"function isValidUrl(str) {\n  try {\n    const url = new URL(str);\n    return url.protocol === \"https:\" || url.protocol === \"http:\";\n  } catch {\n    return false;\n  }\n}\n\nfunction escapeRegExp(str) {\n  return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n// --- Main ---\n\nconst args = process.argv.slice(2);\n\nif (args.length === 0) {\n  console.error(\"Usage: node validate-companies.js <file1.md> [file2.md ...]\");\n  process.exit(2);\n}\n\n// Separate company files from old-format files\nconst companyFiles = [];\nconst oldFormatFiles = [];\n\nfor (const file of args) {\n  // Strip pr-head/ prefix used in pull_request_target checkout\n  const normalized = file.replace(/^pr-head\\//, \"\");\n  if (normalized.startsWith(\"company-profiles/\")) {\n    oldFormatFiles.push(normalized);\n  } else if (normalized.startsWith(\"src/companies/\") && normalized.endsWith(\".md\")) {\n    // Store both the actual path (for reading) and the display path (for output)\n    companyFiles.push({ actual: file, display: normalized });\n  }\n}\n","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/remoteintech/remote-jobs/blob/b1dd8deb1945e5ff58f9e9c35e318f53c8871930/.github/scripts/validate-companies.js#L192-L228","documentation":"CLI usage guard at validate-companies.js:209-212. The script reads process.argv.slice(2); if that array is empty it writes the usage line to stderr and calls process.exit(2). Exit code 2 is deliberately distinct from the exit 1 used for validation failures, so callers can tell 'wrong invocation' from 'bad input'.","triggerScenarios":"Running `node .github/scripts/validate-companies.js` with no arguments; a wrapper npm script that didn't forward `--` args; a GitHub Actions step whose changed-files glob resolved to an empty list, so the validator was invoked with zero paths.","commonSituations":"Maintainer runs the script locally without args to 'just try it'; the validate-companies.yml workflow computed the diff list but a path filter matched nothing; pull_request_target checkout produced an empty argument string after path normalization.","solutions":["Pass one or more .md paths: `node .github/scripts/validate-companies.js src/companies/foo.md`.","In CI, gate the validator step on a non-empty changed-files list and skip when empty.","If invoking through npm, use `npm run <script> -- <files>` so args forward correctly.","Treat exit code 2 in your CI scripts as a configuration error, not a content error."],"exampleFix":"// before\nnode .github/scripts/validate-companies.js\n// after\nnode .github/scripts/validate-companies.js src/companies/foo.md src/companies/bar.md","handlingStrategy":"validation","validationCode":"const files = process.argv.slice(2);\nif (files.length === 0) {\n  console.error('Usage: node validate-companies.js <file1.md> [...]');\n  process.exit(2);\n}","typeGuard":null,"tryCatchPattern":"const { status } = spawnSync('node', ['.github/scripts/validate-companies.js', ...files]);\nif (status === 2) {\n  // invocation error — fix the caller, don't retry on the same args\n  throw new Error('validator invoked with no file arguments');\n}","preventionTips":["Gate the CI step on a non-empty changed-files list and skip cleanly when empty.","Forward args correctly through npm with `--`.","Treat exit code 2 distinctly from exit 1 in CI reporting."],"tags":["cli","argv","ci","validation"],"backgroundTag":null,"analyzedSha":"b1dd8deb1945e5ff58f9e9c35e318f53c8871930","analyzedAt":"2026-08-13T04:09:00.804Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}