santifer/career-ops · error

glints: untrusted hostname

Error message

glints: untrusted hostname "${parsed.hostname}" — must be one of: ${[...ALLOWED_GLINTS_HOSTS].join(', ')}

What it means

assertGlintsUrl allowlists exactly three hosts: glints.com, www.glints.com, and glints.id (ALLOWED_GLINTS_HOSTS). A parsed HTTPS URL on any other hostname triggers this error, which lists the allowed set. Since Glints is accessed through a reverse-engineered endpoint, the allowlist blocks a misconfigured or malicious api override from sending queries elsewhere.

Solutions

  1. Use one of the allowed hosts exactly: glints.com, www.glints.com, or glints.id (e.g. https://glints.com/api/v2-alc/graphql)
  2. Remove the api override entirely to fall back to the vetted default endpoint
  3. If you genuinely need another host (local mock), the allowlist is a hard boundary in provider code — do not bypass it in config; test mocks outside the provider instead

Example fix

// before
api: https://api.glints.com/v2-alc/graphql
// after
api: https://glints.com/api/v2-alc/graphql
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = new Set(['glints.com','www.glints.com','glints.id']);
if (entry.api) {
  const host = new URL(entry.api).hostname;
  if (!ALLOWED.has(host)) throw new Error(`glints entry ${entry.name}: host ${host} not in allowlist`);
}

Type guard

function isAllowedGlintsHost(v) { try { return ['glints.com','www.glints.com','glints.id'].includes(new URL(v).hostname); } catch { return false; } }

Try / catch

try {
  assertGlintsUrl(url);
} catch (e) {
  if (String(e.message).includes('untrusted hostname')) {
    console.error(`Only glints.com, www.glints.com, glints.id are allowed; got ${url}. Remove the api override to use the default.`);
  }
  throw e;
}

Prevention

When it happens

Trigger: A glints entry sets api to a URL on another host — e.g. https://api.glints.com/..., a regional mirror like glints.sg, or a third-party/mock endpoint — and assertGlintsUrl rejects the hostname.

Common situations: Assuming subdomains (api.glints.com) are allowed (they are not — only the three exact hosts); pointing at a staging or self-hosted mock of the GraphQL endpoint; a typo in the configured host.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/ecb72f81b62539a4. Report an issue: GitHub.

Appendix: source

Thrown at providers/glints.mjs:79

      }
      createdAt
    }
    expInfo
    hasMore
  }
}`;

/** @param {string} url */
function assertGlintsUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`glints: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`glints: URL must use HTTPS: ${url}`);
  if (!ALLOWED_GLINTS_HOSTS.has(parsed.hostname))
    throw new Error(`glints: untrusted hostname "${parsed.hostname}" — must be one of: ${[...ALLOWED_GLINTS_HOSTS].join(', ')}`);
  return url;
}

// NaN-safe Date.parse
function toEpochMs(value) {
  if (!value) return undefined;
  const parsed = Date.parse(value);
  return Number.isNaN(parsed) ? undefined : parsed;
}

/**
 * Derive the job detail base URL from the API hostname.
 * @param {string} apiUrl
 * @returns {string}
 */
function deriveBaseUrl(apiUrl) {
  try {
    const parsed = new URL(apiUrl);

View on GitHub (pinned to aac998c7ed)