santifer/career-ops · error · Error

APIFY_TOKEN not set — enable apify in config/plugins.yml and

Error message

APIFY_TOKEN not set — enable apify in config/plugins.yml and add the token to .env

What it means

Thrown by the apify provider's `fetch` hook (plugins/apify/index.mjs:182) when neither `ctx.env.APIFY_TOKEN` (the plugin's scoped env) nor `process.env.APIFY_TOKEN` is set. This is the provider-level guard, richer than the transport-level one (error 112): it names both the config file (config/plugins.yml) and .env so the user knows exactly where to enable the plugin and add the token. It fires before any actor/field_map validation.

Source

Thrown at plugins/apify/index.mjs:182

  };
  for (const [k, v] of Object.entries(defaults || {})) {
    if (!ALLOWED_DEFAULT_KEYS.has(k)) continue;
    if (!out[k]) out[k] = String(v);
  }
  return out;
}

/** The keyed provider hook. Reads APIFY_TOKEN from the plugin's scoped ctx.env. */
export default {
  provider: {
    id: 'apify',
    // Keyed providers never auto-detect (the engine also forces this to null).
    detect() { return null; },

    async fetch(entry, ctx) {
      const token = ctx?.env?.APIFY_TOKEN || process.env.APIFY_TOKEN;
      if (!hasToken(token)) {
        throw new Error('APIFY_TOKEN not set — enable apify in config/plugins.yml and add the token to .env');
      }
      if (!entry.actor) {
        throw new Error(`apify: entry ${entry.name} missing 'actor' (e.g. misceres/indeed-scraper)`);
      }
      if (
        !entry.field_map ||
        !isFieldSpec(entry.field_map.title) ||
        !isFieldSpec(entry.field_map.url) ||
        (entry.field_map.company != null && !isFieldSpec(entry.field_map.company)) ||
        (entry.field_map.location != null && !isFieldSpec(entry.field_map.location)) ||
        (entry.field_map.description != null && !isFieldSpec(entry.field_map.description))
      ) {
        throw new Error(
          `apify: entry ${entry.name} has invalid field_map. Each of title, url, company, ` +
          `location, description must be a string or a non-empty array of strings. title and url are required.`
        );
      }

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Enable the plugin: `node plugins.mjs enable apify` (or set it in config/plugins.yml).
  2. Add `APIFY_TOKEN=apify_api_...` to .env and ensure the env loader populates the plugin's scoped ctx.env.
  3. Run `node doctor.mjs` to confirm the apify plugin reports active with a valid token.
  4. In CI, inject APIFY_TOKEN as a secret.

Example fix

# before — config/plugins.yml missing apify, .env missing token
# after
# config/plugins.yml
apify:
  enabled: true
# .env
APIFY_TOKEN=apify_api_xxxxxxxxxxxxx
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, readFileSync } from 'node:fs';
// Ensure apify is enabled AND the token is present before scanning.
function assertApifyReady(root) {
  const cfg = readFileSync(`${root}/config/plugins.yml`, 'utf-8');
  const enabled = /^apify:\n(?:[ \t]+enabled:[ \t]*true|.{0})|apify:[ \t]*true/m.test(cfg);
  if (!enabled) throw new Error('apify plugin not enabled in config/plugins.yml');
  if (!process.env.APIFY_TOKEN) throw new Error('APIFY_TOKEN missing from .env');
}
assertApifyReady(process.cwd());

Try / catch

try {
  await provider.fetch(entry, ctx);
} catch (err) {
  if (/APIFY_TOKEN not set — enable apify/.test(err.message)) {
    console.error(`Setup required: ${err.message}`);
    process.exitCode = 2;
  } else throw err;
}

Prevention

When it happens

Trigger: The apify provider is referenced (portals.yml entry with `provider: apify`) and its fetch is invoked, but the plugin is not fully configured — either not enabled in config/plugins.yml or the token is absent from both the scoped ctx.env and process.env.

Common situations: Plugin added to portals.yml but never enabled via `node plugins.mjs enable apify`; .env missing APIFY_TOKEN; the plugin's scoped env did not receive the token (env loader scoping issue); running in CI without the secret injected.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/f10ad63760858829. Report an issue: GitHub.