decolua/9router · error · Error
Zed callback must include user_id and access_token
Error message
Zed callback must include user_id and access_token
What it means
After parsing the Zed callback payload (JSON or URL query), parseZedCallbackPayload requires both a user id (`user_id`/`userId`) and an encrypted access token (`access_token`/`accessToken`/`token`). If either key is missing or empty it throws this error, because a Zed credential cannot be constructed without both values.
Source
Thrown at open-sse/shared/zedAuth.js:128
let url;
try {
url = new URL(raw);
} catch {
try {
url = new URL(`http://127.0.0.1/?${raw.replace(/^\?/, "")}`);
} catch {
throw new Error("Invalid Zed callback URL");
}
}
url.searchParams.forEach((value, key) => {
data[key] = value;
});
}
const userId = data.user_id || data.userId;
const encryptedAccessToken = data.access_token || data.accessToken || data.token;
if (!userId || !encryptedAccessToken) {
throw new Error("Zed callback must include user_id and access_token");
}
return { userId: String(userId), encryptedAccessToken: String(encryptedAccessToken) };
}
/** Decrypt the RSA-encrypted access token using the stored private key. */
export function decryptZedAccessToken(encryptedAccessToken, privateKeyVerifier) {
const privateKey = decodeZedPrivateKeyVerifier(privateKeyVerifier);
const encrypted = Buffer.from(String(encryptedAccessToken), "base64url");
try {
return crypto
.privateDecrypt(
{ key: privateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: "sha256" },
encrypted,
)
.toString("utf8");
} catch (oaepError) {
try {
return cryptoView on GitHub (pinned to 90b52e06ff)
Solutions
- Inspect the pasted payload: confirm it contains user_id (or userId) AND access_token (or accessToken/token).
- Complete the full OAuth flow so the final redirect includes both params; an intermediate redirect won't do.
- If building the payload manually, include both fields: {"user_id":"...","access_token":"..."}.
- Check for error params in the callback (error/error_description) — if present, re-run sign-in instead of parsing.
Example fix
// before
parseZedCallbackPayload("http://127.0.0.1/?state=xyz"); // no user_id/access_token
// after
parseZedCallbackPayload("http://127.0.0.1/?user_id=42&access_token=ENCRYPTED_B64"); Defensive patterns
Strategy: validation
Validate before calling
function hasZedCallbackFields(raw) {
let data = {};
try { data = JSON.parse(raw); }
catch { try { new URL(`http://x/?${String(raw).replace(/^\?/, "")}`).searchParams.forEach((v, k) => (data[k] = v)); } catch { return false; } }
return Boolean((data.user_id || data.userId) && (data.access_token || data.accessToken || data.token));
}
Type guard
const hasZedPayload = (d) => Boolean(d && (d.user_id || d.userId) && (d.access_token || d.accessToken || d.token));
Try / catch
try {
const payload = parseZedCallbackPayload(input);
} catch (e) {
if (String(e.message).includes("must include")) {
// show which fields were found vs missing; re-run the OAuth flow
} else throw e;
} Prevention
- After OAuth completes, verify the final redirect URL contains both user_id and access_token before parsing.
- Check for `error` query params in the callback and abort with the provider's error_description.
- When constructing payloads manually, validate both keys exist first.
When it happens
Trigger: Calling parseZedCallbackPayload with a parseable URL/JSON that lacks user_id or access_token — e.g. the redirect only carried `state`/`code` params, or the JSON contains differently-named keys.
Common situations: Zed changed its callback param names, the user pasted the initial authorize URL (which has code/state but no tokens), or the callback returned an error payload like `?error=access_denied` instead of tokens.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- access_token is required
- refresh_token is required
- scopes is required
- Missing Zed callback URL
- Invalid Zed callback URL
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/b821b50991f0c4c1.
Report an issue: GitHub.