koala73/worldmonitor · error · Error
Redis EVAL returned an invalid response
Error message
Redis EVAL returned an invalid response
What it means
Thrown by `rawRedisEval` in api/oauth/_refresh-recovery.ts:211 when the Redis REST response is HTTP 200 with no `error`, but the parsed body is null or lacks a `result` property. This is a protocol-shape guard: Upstash always wraps command output in `{ "result": ... }`, so a body without it means an unexpected gateway response, a non-JSON body that `resp.json()` failed to parse (caught → null), or an API version/endpoint mismatch.
Source
Thrown at api/oauth/_refresh-recovery.ts:211
keys: string[],
args: Array<string | number>,
): Promise<unknown> {
const { url, token } = redisConfig();
const resp = await fetch(`${url}/`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'worldmonitor-edge/1.0',
},
body: JSON.stringify(['EVAL', script, String(keys.length), ...keys, ...args]),
signal: AbortSignal.timeout(3_000),
});
if (!resp.ok) throw new Error(`Redis HTTP ${resp.status}`);
const data = (await resp.json().catch(() => null)) as { result?: unknown; error?: string } | null;
if (data?.error) throw new Error(`Redis EVAL failed: ${data.error}`);
if (!data || !Object.prototype.hasOwnProperty.call(data, 'result')) {
throw new Error('Redis EVAL returned an invalid response');
}
return data.result;
}
function parseStoredJson(value: unknown): unknown {
if (typeof value !== 'string') throw new Error('Redis returned an invalid stored value');
try {
return JSON.parse(value);
} catch {
throw new Error('Redis returned malformed JSON');
}
}
export async function rawRedisBeginRefreshAttempt(
refreshToken: string,
attemptId: string,
): Promise<RefreshConsumeResult> {
const refreshKey = `oauth:refresh:${refreshToken}`;View on GitHub (pinned to a96956387a)
Solutions
- Confirm `UPSTASH_REDIS_REST_URL` is a genuine Upstash REST endpoint (ends with `.upstash.io`, no path suffix beyond what the client appends)
- Log/replicate the exact POST body (`['EVAL', ...]`) with curl against the configured URL to see the raw response shape
- If transient, retry — the recovery flow treats this as a retryable failure and preserves the refresh token
Defensive patterns
Strategy: retry
Type guard
function isInvalidRedisResponse(e: unknown): boolean {
return e instanceof Error && e.message === 'Redis EVAL returned an invalid response';
} Try / catch
try {
await beginRefreshAttempt(token, id);
} catch (e) {
if (isInvalidRedisResponse(e)) {
await retryWithBackoff(); // usually transient gateway/shape issue; retryable-safe by design
} else throw e;
} Prevention
- Point UPSTASH_REDIS_REST_URL directly at the Upstash host; avoid transforming proxies
- Alert on reply-shape errors — repeated occurrences indicate endpoint or API changes
When it happens
Trigger: Upstash returning an HTML error/blank page with 200 (proxy or gateway quirk); `resp.json()` throwing and yielding null; a URL pointing at a non-Upstash endpoint that answers 200 with a different JSON shape.
Common situations: `UPSTASH_REDIS_REST_URL` pointing at a proxy or wrong service that returns 200 with different JSON; transient gateway oddities; Upstash API behavior changes.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Redis refresh-attempt consume returned an invalid response
- Redis refresh-attempt restore returned an invalid response
- Redis not configured
- Redis HTTP ${resp.status}
- Redis EVAL failed: ${data.error}
AI-assisted analysis of koala73/worldmonitor@a96956387a (2026-08-27).
Data as JSON: /api/errors/bdc47d786b691c1b.
Report an issue: GitHub.