santifer/career-ops · error · Error
local-parser: parser.command is required
Error message
local-parser: parser.command is required
What it means
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.
Source
Thrown at providers/local-parser.mjs:94
if (Array.isArray(parser.args)) args.push(...parser.args);
return args.map(arg => expandParserArg(arg, entry));
}
// Resolve a configured path and confirm it stays inside the project tree.
function resolveInsideRoot(rawPath) {
const resolved = realpathSync(resolve(PROJECT_ROOT, String(rawPath)));
if (resolved !== PROJECT_ROOT && !resolved.startsWith(PROJECT_ROOT + sep)) {
throw new Error(`local-parser: path escapes the project root: ${rawPath}`);
}
return resolved;
}
// The command is either a whitelisted interpreter (resolved via PATH) or a script
// that lives inside the repo. Anything else is rejected.
function resolveCommand(command) {
const value = String(command || '');
if (!value) throw new Error('local-parser: parser.command is required');
if (!value.includes('/') && ALLOWED_INTERPRETERS.has(value)) return value;
return resolveInsideRoot(value);
}
// Validate the whole invocation and return what to spawn. Throws on anything unsafe.
function resolveInvocation(entry) {
const rawCommand = String(entry.parser?.command || '');
const command = resolveCommand(rawCommand);
const args = buildParserArgs(entry);
const scriptPath = getParserScriptPath(entry);
const usesInterpreter = !rawCommand.includes('/') && ALLOWED_INTERPRETERS.has(rawCommand);
if (usesInterpreter) {
// A whitelisted interpreter must run an in-repo script as its FIRST argument.
// Anything before the script is an interpreter option (node --eval / --require,
// python -c, …) that could execute arbitrary code, so require the script to lead.
if (!scriptPath) throw new Error('local-parser: interpreter command requires an in-repo parser script');
resolveInsideRoot(scriptPath);View on GitHub (pinned to 9b17a8ac97)
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'.
Example fix
# before
- name: Acme
provider: local-parser
parser: { script: parsers/acme.py, args: ['{careers_url}'] }
# after
- name: Acme
provider: local-parser
parser: { command: python3, script: parsers/acme.py, args: ['{careers_url}'] } Defensive patterns
Strategy: validation
Validate before calling
export function hasParserCommand(entry) {
return typeof entry?.parser?.command === 'string' && entry.parser.command.trim().length > 0;
}
// if (!hasParserCommand(entry)) failConfig(`local-parser entry ${entry.name} missing parser.command`); Type guard
/** @param {any} entry */
function hasCommand(entry) {
return Boolean(entry?.parser?.command && String(entry.parser.command).trim());
} Try / catch
try {
await provider.fetch(entry, ctx);
} catch (err) {
if (err.message === 'local-parser: parser.command is required') console.warn(`add parser.command to ${entry.name}`);
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ashby: cannot derive API URL for ${entry.name}
- bamboohr: cannot derive API URL for ${entry.name}
- beesite: cannot resolve search host for ${entry.name}
- gem: cannot derive board id for ${entry.name}
- getro: ${entry.name} needs a numeric 'getro_collection' in p
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/80915fd52f7d2ce7.
Report an issue: GitHub.