{"record":{"id":"80915fd52f7d2ce7","repo":"santifer/career-ops","slug":"local-parser-parser-command-is-required","errorCode":null,"errorMessage":"local-parser: parser.command is required","messagePattern":"local-parser: parser\\.command is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/local-parser.mjs","lineNumber":94,"sourceCode":"  if (Array.isArray(parser.args)) args.push(...parser.args);\n\n  return args.map(arg => expandParserArg(arg, entry));\n}\n\n// Resolve a configured path and confirm it stays inside the project tree.\nfunction resolveInsideRoot(rawPath) {\n  const resolved = realpathSync(resolve(PROJECT_ROOT, String(rawPath)));\n  if (resolved !== PROJECT_ROOT && !resolved.startsWith(PROJECT_ROOT + sep)) {\n    throw new Error(`local-parser: path escapes the project root: ${rawPath}`);\n  }\n  return resolved;\n}\n\n// The command is either a whitelisted interpreter (resolved via PATH) or a script\n// that lives inside the repo. Anything else is rejected.\nfunction resolveCommand(command) {\n  const value = String(command || '');\n  if (!value) throw new Error('local-parser: parser.command is required');\n  if (!value.includes('/') && ALLOWED_INTERPRETERS.has(value)) return value;\n  return resolveInsideRoot(value);\n}\n\n// Validate the whole invocation and return what to spawn. Throws on anything unsafe.\nfunction resolveInvocation(entry) {\n  const rawCommand = String(entry.parser?.command || '');\n  const command = resolveCommand(rawCommand);\n  const args = buildParserArgs(entry);\n  const scriptPath = getParserScriptPath(entry);\n\n  const usesInterpreter = !rawCommand.includes('/') && ALLOWED_INTERPRETERS.has(rawCommand);\n  if (usesInterpreter) {\n    // A whitelisted interpreter must run an in-repo script as its FIRST argument.\n    // Anything before the script is an interpreter option (node --eval / --require,\n    // python -c, …) that could execute arbitrary code, so require the script to lead.\n    if (!scriptPath) throw new Error('local-parser: interpreter command requires an in-repo parser script');\n    resolveInsideRoot(scriptPath);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/local-parser.mjs#L76-L112","documentation":"resolveCommand requires a non-empty parser.command. If entry.parser.command is missing, empty, or coerces to an empty string, this error fires before any path resolution or interpreter lookup happens.","triggerScenarios":"entry.parser is unset, or entry.parser.command is '', null, or undefined. resolveInvocation calls resolveCommand(String(entry.parser?.command || '')), so any falsy value reaches the empty check.","commonSituations":"A local-parser entry was added without a parser block; the parser.command key was misspelled (e.g. cmd); YAML indentation put command under the wrong nesting; the value was left blank.","solutions":["Add parser.command to the entry (a whitelisted interpreter like 'python3' or an in-repo script path).","Check YAML indentation — parser.command must be nested under parser:.","Confirm the key is spelled exactly 'command'."],"exampleFix":"# before\n- name: Acme\n  provider: local-parser\n  parser: { script: parsers/acme.py, args: ['{careers_url}'] }\n\n# after\n- name: Acme\n  provider: local-parser\n  parser: { command: python3, script: parsers/acme.py, args: ['{careers_url}'] }","handlingStrategy":"validation","validationCode":"export function hasParserCommand(entry) {\n  return typeof entry?.parser?.command === 'string' && entry.parser.command.trim().length > 0;\n}\n// if (!hasParserCommand(entry)) failConfig(`local-parser entry ${entry.name} missing parser.command`);","typeGuard":"/** @param {any} entry */\nfunction hasCommand(entry) {\n  return Boolean(entry?.parser?.command && String(entry.parser.command).trim());\n}","tryCatchPattern":"try {\n  await provider.fetch(entry, ctx);\n} catch (err) {\n  if (err.message === 'local-parser: parser.command is required') console.warn(`add parser.command to ${entry.name}`);\n  throw err;\n}","preventionTips":["Schema-validate portals.yml so every provider: local-parser entry has a non-empty parser.command.","Check YAML indentation: parser.command must sit under the parser: map.","Fail fast at config load rather than at fetch time."],"tags":["config","local-parser","missing-field","provider-config"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}