santifer/career-ops · error · Error
Apify actor ${actorId} finished with status ${run.status}${r
Error message
Apify actor ${actorId} finished with status ${run.status}${reason} What it means
Thrown by `runActor` (plugins/apify/_apify.mjs:199) when the actor run reaches a terminal status other than SUCCEEDED — i.e. FAILED, ABORTED, or TIMED-OUT. The `waitForRun` loop returns the run object once status is in TERMINAL_STATUSES; runActor then checks `if (run.status !== 'SUCCEEDED')` and throws, appending `run.statusMessage` as `: <reason>` if present. The dataset is not fetched on failure.
Source
Thrown at plugins/apify/_apify.mjs:199
if (!Array.isArray(items)) {
throw new Error(`Apify run ${runId} returned non-array dataset payload`);
}
return items;
}
export async function runActor(actorId, input, { timeoutMs = DEFAULT_RUN_TIMEOUT_MS, token = process.env.APIFY_TOKEN } = {}) {
if (!token) throw new Error('APIFY_TOKEN not set');
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
throw new Error(`apify: invalid timeoutMs ${JSON.stringify(timeoutMs)} (must be a positive finite number of milliseconds)`);
}
// Single deadline shared across startRun → waitForRun → fetchDatasetItems so
// the caller's timeoutMs is the end-to-end ceiling, not just the wait loop.
const deadline = Date.now() + timeoutMs;
const runId = await startRun(actorId, input, token, deadline);
const run = await waitForRun(runId, token, deadline, timeoutMs);
if (run.status !== 'SUCCEEDED') {
const reason = run.statusMessage ? `: ${run.statusMessage}` : '';
throw new Error(`Apify actor ${actorId} finished with status ${run.status}${reason}`);
}
return await fetchDatasetItems(runId, token, deadline);
}
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Read the statusMessage suffix — Apify usually states the failure cause.
- Open the run on the Apify console (runId is in the message) for full logs.
- Fix the actor input (field_map / input in portals.yml) to match the actor's expected schema.
- If the actor itself is broken, switch to an updated actor or contact its maintainer.
Defensive patterns
Strategy: try-catch
Try / catch
try {
const items = await runActor(actorId, input, opts);
} catch (err) {
if (/finished with status (FAILED|ABORTED|TIMED-OUT)/.test(err.message)) {
console.error(`Apify actor ${actorId} did not succeed: ${err.message}`);
// inspect the runId in the message on the Apify console for logs
} else throw err;
} Prevention
- Validate actor input against the actor's documented schema before running.
- Monitor actor health on the Apify console; switch actors when a target site changes.
When it happens
Trigger: The actor finished but failed (input error, scraper bug), was aborted (manually or by Apify), or hit Apify's own run timeout. waitForRun returns the terminal run, and runActor rejects.
Common situations: Bad actor input (wrong field names, missing required input); the target site changed and the scraper broke; Apify aborted the run due to proxy/quota exhaustion; the actor timed out internally on Apify's side before your timeoutMs.
Related errors
- [models] Failed to fetch free model list: ${reason}. Check t
- OPENROUTER_API_KEY not found. Copy .env.example to .env and
- HTTP ${resp.status}: ${t.slice(0, 120)}
- apify: invalid actorId ${JSON.stringify(actorId)}. Expected
- Apify did not return a run id: ${JSON.stringify(body).slice(
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/a434332173cc5c16.
Report an issue: GitHub.