santifer/career-ops · error · Error

wttj: unexpected Algolia app id "${appId}"

Error message

wttj: unexpected Algolia app id "${appId}"

What it means

The parsed PUBLIC_ALGOLIA_APPLICATION_ID must match ^[A-Z0-9]{6,16}$i. This validates the Algolia app id so the derived hostname (${appId}-dsn.algolia.net) cannot be attacker-shaped if /api/env is ever tampered. Throws when the id is missing, empty after trim, or a different shape.

Source

Thrown at providers/wttj.mjs:67

 * Algolia application id + client search key.
 * @param {string} text
 * @returns {{ appId: string, apiKey: string }}
 */
export function parseEnvPayload(text) {
  const start = text.indexOf('{');
  const end = text.lastIndexOf('}');
  if (start === -1 || end <= start) throw new Error('wttj: /api/env payload has no JSON object');
  let env;
  try {
    env = JSON.parse(text.slice(start, end + 1));
  } catch {
    throw new Error('wttj: /api/env payload is not valid JSON');
  }
  const appId = typeof env.PUBLIC_ALGOLIA_APPLICATION_ID === 'string' ? env.PUBLIC_ALGOLIA_APPLICATION_ID.trim() : '';
  const apiKey = typeof env.PUBLIC_ALGOLIA_API_KEY_CLIENT === 'string' ? env.PUBLIC_ALGOLIA_API_KEY_CLIENT.trim() : '';
  // App ids are short alphanumerics; validating keeps the derived Algolia
  // hostname from being attacker-shaped if the env payload ever changes.
  if (!/^[A-Z0-9]{6,16}$/i.test(appId)) throw new Error(`wttj: unexpected Algolia app id "${appId}"`);
  // The key is only ever sent as a request header (never used to build a
  // host), so don't over-constrain its format — WTTJ may rotate to a longer
  // or non-hex (e.g. secured/base64) client key. Length bounds only.
  if (!apiKey || apiKey.length < 16 || apiKey.length > 500) {
    throw new Error('wttj: unexpected Algolia api key shape');
  }
  return { appId, apiKey };
}

/**
 * Normalize a single Algolia hit. Exported for tests.
 *
 * Field mapping → normalized Job shape:
 *   - title:    `name`
 *   - url:      /en/companies/{organization.slug}/jobs/{slug} on the WTTJ site
 *   - company:  `organization.name`
 *   - location: offices[0] city+country, with ", Remote" appended when the
 *               posting allows fulltime remote

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Fetch /api/env and check the actual value of PUBLIC_ALGOLIA_APPLICATION_ID.
  2. If WTTJ rotated to a validly-shaped id, no code change is needed (just rerun).
  3. If the format genuinely changed (e.g. longer), widen the regex in parseEnvPayload after confirming the new shape against Algolia's docs.
  4. If the key was renamed, update the two field reads in parseEnvPayload.

Example fix

// if WTTJ rotates to a longer app id (e.g. 20 chars):
// before
if (!/^[A-Z0-9]{6,16}$/i.test(appId)) throw new Error(`wttj: unexpected Algolia app id "${appId}"`);
// after
if (!/^[A-Z0-9]{6,24}$/i.test(appId)) throw new Error(`wttj: unexpected Algolia app id "${appId}"`);
Defensive patterns

Strategy: validation

Validate before calling

const APPID_RE = /^[A-Z0-9]{6,16}$/i;
if (!APPID_RE.test(parsedAppId))
  console.warn("wttj app id shape changed:", parsedAppId);

Type guard

const isValidAlgoliaAppId = (s) => typeof s === "string" && /^[A-Z0-9]{6,16}$/i.test(s);

Try / catch

try { parseEnvPayload(envText); }
catch (err) {
  if (/Algolia app id/.test(err.message)) { logUpstreamChange("wttj", err.message); }
  throw err;
}

Prevention

When it happens

Trigger: /api/env no longer contains PUBLIC_ALGOLIA_APPLICATION_ID; the field was renamed; WTTJ rotated to an app id format outside the 6–16 alphanumeric range; the env object parsed but the key is absent.

Common situations: WTTJ renamed the env key; WTTJ's Algolia app id changed length/format; a tampered env payload.

Related errors


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