santifer/career-ops · error · Error

glints: HTTP ${err.status} — ${detail}

Error message

glints: HTTP ${err.status} — ${detail}

What it means

glints.mjs throws this in graphqlPage() when ctx.fetchJson rejects with an error that carries both .status and .body — i.e. a non-2xx HTTP response with a body. The handler tries to parse the body as JSON and extract errors[0].message, falling back to the first 200 chars of the raw body. So the thrown text identifies the HTTP status and the server's error detail, which for Glints is most often a WAF/firewall block, rate limiting, or a request the server rejected.

Source

Thrown at providers/glints.mjs:176

        'user-agent': BROWSER_LIKE_USER_AGENT,
        'origin': 'https://glints.com',
        'referer': 'https://glints.com/id/opportunities/jobs/explore',
      },
      body,
      redirect: 'error',
    });
    return res;
  } catch (err) {
    // On POST, some servers return non-JSON errors; attempt text fallback
    if (err.status && err.body) {
      let detail = '';
      try {
        const parsed = JSON.parse(err.body);
        detail = parsed.errors?.[0]?.message || err.body.slice(0, 200);
      } catch {
        detail = err.body.slice(0, 200);
      }
      throw new Error(`glints: HTTP ${err.status} — ${detail}`);
    }
    throw err;
  }
}

/** @type {Provider} */
export default {
  id: 'glints',

  detect(_entry) {
    // Glints is a job board aggregator, not a company ATS.
    // Auto-detection is intentionally not supported —
    // use `provider: glints` explicitly in portals.yml.
    return null;
  },

  async fetch(entry, ctx) {
    const apiUrl = entry.api || DEFAULT_API;

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Read the status and detail in the message: 429 → slow down (raise the inter-page delay / lower maxPages); 403 → the WAF is blocking this IP/UA, route through a residential egress or back off; 5xx → transient, retry.
  2. Confirm BROWSER_LIKE_USER_AGENT and the origin/referer headers in graphqlPage() still match a current Chrome UA; update if Glints tightened fingerprinting.
  3. Reduce pageSize or maxPages in portals.yml and add delay between runs to stay under rate limits.
  4. If the detail shows a GraphQL validation error, re-capture the current searchJobsV3 query from a live browser session and update DEFAULT_GRAPHQL_QUERY.

Example fix

# before (aggressive)
- name: Glints (ID)
  provider: glints
  pageSize: 100
  maxPages: 20

# after (gentler, avoids 429/403)
- name: Glints (ID)
  provider: glints
  pageSize: 30
  maxPages: 3
Defensive patterns

Strategy: retry

Type guard

// Identify a retriable Glints HTTP error (transient 5xx / rate limit).
function isRetriableGlintsError(err) {
  const m = /glints: HTTP (\d{3})/.exec(err.message || '');
  if (!m) return false;
  const s = Number(m[1]);
  return s === 429 || s >= 500;
}

Try / catch

// Retry transient Glints failures with backoff; surface the rest.
async function fetchGlintsResilient(entry, ctx) {
  for (let attempt = 0; attempt < 3; attempt++) {
    try { return await glintsProvider.fetch(entry, ctx); }
    catch (err) {
      if (attempt < 2 && isRetriableGlintsError(err)) {
        await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
        continue;
      }
      throw err;
    }
  }
}

Prevention

When it happens

Trigger: Glints' firewall blocks the request because the User-Agent/origin/referer headers look non-browser (the code already sends a Chrome UA, so a block usually means the header set changed or the IP is flagged); HTTP 429 rate limiting; HTTP 5xx from Glints; a malformed GraphQL body the server rejects with 400; an anti-bot challenge page returned as the body.

Common situations: Running scans from a cloud/datacenter IP that Glints' WAF flags; scanning too aggressively and hitting 429; a Glints-side schema change making the query invalid (400); transient 5xx during their incident.

Related errors


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