decolua/9router · info

[ProxyFetch] got-scraping unavailable, falling back to nativ

Error message

[ProxyFetch] got-scraping unavailable, falling back to native fetch: ${e.message}

What it means

proxyFetch optionally loads got-scraping for browser-like TLS/JA3 fingerprints to defeat TLS-based bot detection. This lazy import is wrapped in try/catch; when the module can't be imported (not installed, install failure, unsupported platform), it warns once and falls back to native fetch. Requests still work but may be blocked by TLS-fingerprinting providers.

Source

Thrown at open-sse/utils/proxyFetch.js:24

const proxyDispatchers = new Map();

// ─── TLS fingerprinting via got-scraping (browser-like JA3) ───────────────
// Disabled: not in use. Kept commented for future re-enable.
// Restore the original block to re-enable per-host JA3 spoofing.
/*
let _gotScraping = null;
let _gotScrapingChecked = false;
const _gotScrapingLoggedHosts = new Set();

async function getGotScraping() {
  if (_gotScrapingChecked) return _gotScraping;
  _gotScrapingChecked = true;
  try {
    const mod = await import("got-scraping");
    _gotScraping = typeof mod.gotScraping === "function" ? mod.gotScraping : null;
    if (_gotScraping) dbg("TLS", "got-scraping loaded (browser-like JA3 enabled)");
  } catch (e) {
    console.warn(`[ProxyFetch] got-scraping unavailable, falling back to native fetch: ${e.message}`);
    _gotScraping = null;
  }
  return _gotScraping;
}

async function gotScrapingFetch(url, options) {
  const gs = await getGotScraping();
  if (!gs) return null;

  const method = (options.method || "GET").toUpperCase();
  const headersInit = options.headers || {};
  const headers = headersInit instanceof Headers
    ? Object.fromEntries(headersInit.entries())
    : { ...headersInit };

  return new Promise((resolve, reject) => {
    let settled = false;
    const stream = gs.stream({

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Install the optional dependency: npm i got-scraping (or reinstall without --omit=optional)
  2. Confirm the deploy artifact actually includes node_modules/got-scraping
  3. If TLS fingerprinting isn't needed, ignore this warning — native fetch is used automatically
  4. Pin a Node version compatible with got-scraping (>=16) if import fails on old runtimes
  5. For providers that block non-browser TLS, keep got-scraping installed or route through a proxy that rewrites TLS

Example fix

// before: optional deps skipped
npm install --omit=optional
// after
npm install  # includes optionalDependencies: got-scraping
Defensive patterns

Strategy: fallback

Validate before calling

let hasGotScraping = false;
try { await import('got-scraping'); hasGotScraping = true; }
catch { console.warn('got-scraping missing — TLS fingerprinting disabled'); }

Type guard

const tlsImpersonationAvailable = () => hasGotScraping === true;
if (!tlsImpersonationAvailable()) console.info('native fetch will be used');

Try / catch

try {
  return await proxyAwareFetch(url, { impersonate: true });
} catch (e) {
  if (/got-scraping unavailable/i.test(e.message)) {
    return fetch(url); // degrade to native fetch
  }
  throw e;
}

Prevention

When it happens

Trigger: Dynamic import('got-scraping') throws — the optional dependency was never installed, a broken native/ESM install, bundler stripped the dynamic import, or the runtime can't resolve it (Node version/ESM interop issue).

Common situations: Ran npm install with --omit=optional; got-scraping native build failed on the platform; running inside a minimal Docker image or bundled serverless package without the module; older Node without ESM support for the package.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/d5df73afaaa1fbe5. Report an issue: GitHub.