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
- Verify the `rpc` URL resolves to the intended network and, for Helius, that the API key is valid and set in the env.
- 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.
- On 401, rotate/regenerate the Helius key and redeploy.
- 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
- Set a valid Helius API key (or another keyed RPC) to avoid public-RPC 429s.
- Add a secondary RPC and retry once on transport errors.
- Rely on the existing ISR cache to stay under rate limits.
- Never let a single RPC failure crash the page — always degrade to null + warning.
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
- GitHub API error: ${response.status}
- RPC ${method}: ${json.error.message}
- Jupiter HTTP ${res.status}
- pump.fun swap-api HTTP ${res.status}
- Failed to fetch releases
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/8082fc9df69c276d.
Report an issue: GitHub.