koala73/worldmonitor · error · Error
Redis HTTP ${resp.status}
Error message
Redis HTTP ${resp.status} What it means
getLargeRawJson performs a GET against the Upstash Redis HTTP API and throws a plain Error 'Redis HTTP <status>' when the HTTP response is not ok. This signals a transport/API-level failure (auth, rate limit, gateway error) rather than a missing key — a null result is returned separately for that. readCanonicalFallback callers see this as a hard read failure and should treat Redis as unavailable.
Source
Thrown at server/_shared/redis.ts:192
export async function getLargeRawJson(key: string, timeoutMs?: number): Promise<unknown | null> {
if (process.env.LOCAL_API_MODE === 'tauri-sidecar') {
const { sidecarCacheGet } = await import('./sidecar-cache');
return sidecarCacheGet(key);
}
const url = process.env.UPSTASH_REDIS_REST_URL;
const token = process.env.UPSTASH_REDIS_REST_TOKEN;
if (!url || !token) return null;
const resp = await fetch(`${url}/`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'worldmonitor-server/1.0 (redis)',
},
body: JSON.stringify(['GET', key]),
signal: AbortSignal.timeout(resolvePipelineTimeoutMs(timeoutMs)),
});
if (!resp.ok) throw new Error(`Redis HTTP ${resp.status}`);
const data = (await resp.json()) as { result?: string | null; error?: string };
if (data.error) throw new Error(`Redis command error: ${data.error}`);
if (!data.result) return null;
return unwrapEnvelope(JSON.parse(data.result)).data;
}
/**
* Read a key's value as a raw Upstash string — no JSON.parse, no envelope unwrap.
* Use when a seeder stores a bare scalar (e.g., a snapshot_id pointer) via
* `['SET', key, bareString]` without JSON.stringify. getCachedJson() on these
* keys silently returns null because JSON.parse throws on unquoted strings,
* and the try/catch swallows the error.
*
* Always uses the raw (unprefixed) key — matches the seed-script write path
* (seeders don't know about the Vercel env-prefix scheme).
*/
export async function getCachedRawString(key: string): Promise<string | null> {
if (process.env.LOCAL_API_MODE === 'tauri-sidecar') {View on GitHub (pinned to 9361220cc0)
Solutions
- Check the status code in the message: 401/403 means fix UPSTASH credentials, 429 means quota/rate limit, 5xx means retry later or check Upstash status
- Verify UPSTASH_REST_URL and UPSTASH_REST_TOKEN env vars are set correctly in the deployment
- Check the Upstash console for quota exhaustion or plan limits and upgrade/backoff as needed
- Retry with backoff; callers like readCanonicalFallback should fall back to the provider source when Redis is unavailable
Example fix
// before
const v = await getLargeRawJson(key); // throws on HTTP failure
// after
let v = null;
try { v = await getLargeRawJson(key); }
catch (e) { console.warn('redis read failed, falling back', e); } Defensive patterns
Strategy: try-catch
Validate before calling
const redisConfigured = Boolean(process.env.UPSTASH_REST_URL && process.env.UPSTASH_REST_TOKEN); if (!redisConfigured) skipRedisAndUseFallback();
Type guard
function isRedisHttpError(e: unknown): e is Error & { redis: true } {
return e instanceof Error && /^Redis HTTP \d+$/.test(e.message);
} Try / catch
try {
data = await getLargeRawJson(key);
} catch (e) {
log.warn('redis GET failed', e);
data = null; // fall back to provider/source read
} Prevention
- Verify UPSTASH_REST_URL/TOKEN in every environment before deploy
- Monitor Upstash quota and set alerts before limits are hit
- Wrap Redis reads with timeout + fallback so outages degrade gracefully
- Retry 5xx/429 with exponential backoff instead of failing immediately
When it happens
Trigger: The fetch to the Upstash REST endpoint returns a non-2xx status: 401/403 from bad or rotated UPSTASH credentials, 429 from exceeding Upstash request quota, 5xx from Upstash or an intermediate proxy, or a network-layer error surfaced as a bad status.
Common situations: Missing or stale UPSTASH_REST_URL/UPSTASH_REST_TOKEN env vars in a fresh deploy; Upstash free-tier daily command limit exhausted; Upstash incident causing 502/503; wrong region URL after migrating the database.
Related errors
- Redis HTTP ${resp.status}
- Failed to enqueue scenario job
- Redis not configured
- Redis EVAL failed: ${data.error}
- Redis EVAL returned an invalid response
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/8c921dd090ecdb0c.
Report an issue: GitHub.