jamiepine/voicebox · warning · Error

RPC ${method} HTTP ${res.status}

Error message

RPC ${method} HTTP ${res.status}

What it means

Thrown by `rpcCall()` in `landing/src/lib/token-stats.ts` (line 269) when a Solana/Helius JSON-RPC POST returns a non-2xx HTTP status, before the body is even parsed. The endpoint is configurable (a public mainnet RPC fallback or a Helius keyed URL). The whole token-stats module is designed to 'never throw' — each sub-fetch is isolated and failures degrade that metric to `null` plus a `warnings` entry — so this error is caught one level up and never reaches the page.

Source

Thrown at landing/src/lib/token-stats.ts:269

    marketCapUsd,
    creatorRewardsSol,
    creatorRewardsUsd,
    circulating,
    updatedAt: Date.now(),
    warnings,
  };
}

// ── Solana / Helius RPC primitives ───────────────────────────────────────────

async function rpcCall<T>(rpc: string, method: string, params: unknown): Promise<T> {
  const res = await fetch(rpc, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    next: { revalidate: REVALIDATE_S },
    body: JSON.stringify({ jsonrpc: '2.0', id: 'voicebox', method, params }),
  });
  if (!res.ok) throw new Error(`RPC ${method} HTTP ${res.status}`);
  const json = (await res.json()) as { result?: T; error?: { message: string } };
  if (json.error) throw new Error(`RPC ${method}: ${json.error.message}`);
  if (json.result === undefined) throw new Error(`RPC ${method}: empty result`);
  return json.result;
}

interface SupplyResult {
  value: { amount: string; decimals: number; uiAmount: number | null };
}
async function getTokenSupply(
  rpc: string,
): Promise<{ uiAmount: number; decimals: number }> {
  const r = await rpcCall<SupplyResult>(rpc, 'getTokenSupply', [MINT]);
  const decimals = r.value.decimals;
  const uiAmount =
    r.value.uiAmount ?? Number(r.value.amount) / 10 ** decimals;
  return { uiAmount, decimals };
}

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Verify the `rpc` URL resolves to the intended network and, for Helius, that the API key is valid and set in the env.
  2. On 429 from the public RPC, switch to a keyed Helius endpoint with higher limits and rely on the existing ISR cache to stay under quota.
  3. On 401, rotate/regenerate the Helius key and redeploy.
  4. On 5xx, fall back to the alternate RPC — the module already isolates failures, so add a secondary RPC URL and retry once.

Example fix

// before
const res = await fetch(rpc, { method: 'POST', ... });
if (!res.ok) throw new Error(`RPC ${method} HTTP ${res.status}`);

// after — retry once against a fallback RPC on transport errors
async function rpcCall<T>(rpc: string, fallback: string | undefined, method: string, params: unknown) {
  for (const url of [rpc, fallback].filter(Boolean) as string[]) {
    try {
      const res = await fetch(url, { method:'POST', headers:{'Content-Type':'application/json'}, next:{revalidate:REVALIDATE_S}, body: JSON.stringify({jsonrpc:'2.0',id:'voicebox',method,params}) });
      if (res.ok) return (await res.json()).result as T;
    } catch { /* try next */ }
  }
  throw new Error(`RPC ${method} failed on all endpoints`);
}
Defensive patterns

Strategy: fallback

Validate before calling

// Prefer a keyed Helius endpoint; validate the URL before use
function resolveRpc(): string {
  const keyed = process.env.HELIUS_RPC_URL;
  if (keyed && /^https:\/\//.test(keyed)) return keyed;
  return PUBLIC_MAINNET_RPC; // public fallback
}

Type guard

function isRpcHttpError(e: unknown): boolean {
  return /RPC .* HTTP \d+/.test(String((e as Error)?.message ?? ''));
}

Try / catch

// The module already isolates failures — mirror that pattern
try {
  return await rpcCall(rpc, method, params);
} catch (e) {
  warnings.push(`${method}: ${(e as Error).message}`);
  return null; // degrade this metric, keep the page rendering
}

Prevention

When it happens

Trigger: RPC endpoint is down or returning 5xx; the Helius URL has a missing/invalid API key -> 401; the public RPC rate limit hit -> 429; the configured `rpc` string is malformed or points at the wrong network (e.g. devnet) returning 404; CORS/network failure reaching the RPC host.

Common situations: Helius API key not set or revoked so keyed calls 401; public mainnet RPC rate-limited under load (the 10-min cache usually prevents this but a cold cache under concurrent requests can exceed it); wrong `rpc` env var after a deploy; RPC provider incident.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/8082fc9df69c276d. Report an issue: GitHub.