santifer/career-ops · error · Error
local-parser: the parser script must be the interpreter's fi
Error message
local-parser: the parser script must be the interpreter's first argument
What it means
For a whitelisted interpreter, the parser script must be args[0] — the interpreter's first argument. If anything precedes the script (an interpreter option like --eval, --require, -c, --inspect), this error fires. The rule blocks interpreter options that could execute arbitrary code (node --eval '...', python -c '...').
Source
Thrown at providers/local-parser.mjs:114
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);
if (args[0] !== scriptPath) {
throw new Error('local-parser: the parser script must be the interpreter\'s first argument');
}
} else if (scriptPath) {
// command is an in-repo file; keep any detected script path inside the repo too.
resolveInsideRoot(scriptPath);
}
return { command, args };
}
function normalizeJobUrl(rawUrl, baseUrl) {
if (!rawUrl) return '';
try {
return new URL(String(rawUrl).trim(), baseUrl || undefined).href;
} catch {
return '';
}
}
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Reorder parser.args so the script path is first: args: ['parsers/acme.py', '--require','./hook.js'] (note: options after the script are passed to the script, not the interpreter — adjust accordingly).
- If you need interpreter options, do not use local-parser's argv expansion; wrap the invocation in an in-repo shell script instead.
- Remove any leading --eval/-c style options.
Example fix
# before
parser:
command: node
script: parsers/acme.js
args: ['--require', './hook.js', 'parsers/acme.js']
# after (hook logic moved inside the parser script)
parser:
command: node
script: parsers/acme.js
args: ['parsers/acme.js', '{careers_url}'] Defensive patterns
Strategy: validation
Validate before calling
const INTERPRETERS = new Set(['python3','python','node','deno','bun','sh','bash']);
export function scriptIsFirstArg(entry) {
const cmd = String(entry?.parser?.command || '');
if (!INTERPRETERS.has(cmd)) return true;
const script = entry?.parser?.script;
const args = Array.isArray(entry?.parser?.args) ? entry.parser.args : [];
return !script || args[0] === script;
} Type guard
const INTERPRETERS = new Set(['python3','python','node','deno','bun','sh','bash']);
/** @param {any} entry */
function argsLeadWithScript(entry) {
const cmd = String(entry?.parser?.command || '');
if (!INTERPRETERS.has(cmd)) return true;
const script = entry?.parser?.script;
const args = Array.isArray(entry?.parser?.args) ? entry.parser.args : [];
return !script || args[0] === script;
} Try / catch
try {
await provider.fetch(entry, ctx);
} catch (err) {
if (err.message.includes("first argument")) console.warn(`reorder parser.args so the script leads for ${entry.name}`);
throw err;
} Prevention
- Always place the script path as the first element of parser.args when using an interpreter command.
- Move any interpreter setup (--require, hooks) into the script itself rather than the argv.
- Lint parser.args to ensure no leading options precede the script for interpreter commands.
- Treat this error as a code-execution-guard trip — do not silence it by reordering blindly.
When it happens
Trigger: parser.args lists an option before the script, e.g. args: ['--require','./hook.js','parsers/acme.py'], or the script is not the first element. args[0] !== scriptPath triggers the throw.
Common situations: A developer tried to inject a --require hook or environment setup before the script; args ordering was changed; the script was placed later in the array by mistake.
Related errors
- local-parser: interpreter command requires an in-repo parser
- local-parser: company name cannot start with '-': ${value}
- local-parser: careers_url is not a valid URL: ${value}
- local-parser: careers_url must be http(s): ${value}
- local-parser: path escapes the project root: ${rawPath}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/b1e5e743d5b35389.
Report an issue: GitHub.