santifer/career-ops · error
glints: HTTP
Error message
glints: HTTP ${err.status} — ${detail} What it means
graphqlPage issues the reverse-engineered GraphQL search request against Glints' v2-alc endpoint. When the HTTP layer raises an error carrying a status and body, the code tries JSON.parse(err.body) to extract errors[0].message as the detail; if that fails it falls back to the first 200 chars of the body, then throws 'glints: HTTP {status} — {detail}'. The message surfaces the upstream status plus whatever error detail the server returned.
Solutions
- Read the detail after 'HTTP <status> —' in the message: it contains the GraphQL error message or raw body prefix identifying the server-side complaint
- For 4xx schema drift, re-capture the current query from glints.com/id devtools and update graphqlQuery (custom query field on the entry) or the provider's DEFAULT_GRAPHQL_QUERY
- For 403/429, back off and retry later, reduce maxPages/pageSize, and confirm no proxy is interfering; consider being gentler with request frequency
- For 5xx, treat as transient — retry after a delay; check glints.com status if it persists
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight schema check before paginating:
const probe = await fetch('https://glints.com/api/v2-alc/graphql', { method: 'POST', headers: {'content-type':'application/json'}, body: JSON.stringify({ query: DEFAULT_GRAPHQL_QUERY, variables: { data: buildSearchCondition({}) } }) });
if (!probe.ok) console.warn(`glints GraphQL probe returned ${probe.status} — schema or access issue`); Type guard
function isGlintsHttpError(e) { return e && typeof e.status === 'number' && typeof e.body === 'string'; } Try / catch
try {
const page = await graphqlPage(variables, offset);
} catch (e) {
const m = /glints: HTTP (\d+)/.exec(e.message);
if (m && (m[1] === '429' || m[1].startsWith('5'))) {
await sleep(backoffMs);
return graphqlPage(variables, offset); // retry transient failures
}
if (m && m[1].startsWith('4')) console.error(`Glints query rejected (${m[1]}) — likely schema drift; re-capture query from glints.com devtools`);
throw e;
} Prevention
- Expect schema drift — the GraphQL schema is reverse-engineered; re-capture the query from glints.com when 4xx errors start
- Throttle page size/maxPages and add delays to avoid 429s
- Log the error detail (errors[0].message or body prefix) — it names the server-side cause directly
- Wrap pagination in retry-with-backoff for 5xx and 429
When it happens
Trigger: The Glints GraphQL endpoint returns a non-2xx response: a 4xx for a malformed/changed query (the searchJobsV3 schema is reverse-engineered and may change), a 403/429 from bot protection or rate limiting, or a 5xx outage. graphqlPage then throws with the status and body-derived detail.
Common situations: Glints renames or restructures the searchJobsV3 operation (schema drift — the file explicitly warns the schema may change); rate limiting or Cloudflare blocking the browser-like user-agent; transient 5xx during an incident; pageSize/maxPages pushing the server to reject a request.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- API error: code=
- arbeitnow: unexpected API response on page
- gem: JobBoardList failed
- glints: unexpected API response
- HTTP
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/080cbf5d00e33711.
Report an issue: GitHub.
Appendix: 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 aac998c7ed)