{"record":{"id":"aa9a26b69613e290","repo":"decolua/9router","slug":"invalid-zed-callback-url","errorCode":null,"errorMessage":"Invalid Zed callback URL","messagePattern":"Invalid Zed callback URL","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"open-sse/shared/zedAuth.js","lineNumber":117,"sourceCode":"}\n\n/** Parse the pasted native-app callback URL/JSON/query into userId + encrypted token. */\nexport function parseZedCallbackPayload(input) {\n  const raw = String(input || \"\").trim();\n  if (!raw) throw new Error(\"Missing Zed callback URL\");\n\n  let data = {};\n  try {\n    data = JSON.parse(raw);\n  } catch {\n    let url;\n    try {\n      url = new URL(raw);\n    } catch {\n      try {\n        url = new URL(`http://127.0.0.1/?${raw.replace(/^\\?/, \"\")}`);\n      } catch {\n        throw new Error(\"Invalid Zed callback URL\");\n      }\n    }\n    url.searchParams.forEach((value, key) => {\n      data[key] = value;\n    });\n  }\n\n  const userId = data.user_id || data.userId;\n  const encryptedAccessToken = data.access_token || data.accessToken || data.token;\n  if (!userId || !encryptedAccessToken) {\n    throw new Error(\"Zed callback must include user_id and access_token\");\n  }\n  return { userId: String(userId), encryptedAccessToken: String(encryptedAccessToken) };\n}\n\n/** Decrypt the RSA-encrypted access token using the stored private key. */\nexport function decryptZedAccessToken(encryptedAccessToken, privateKeyVerifier) {\n  const privateKey = decodeZedPrivateKeyVerifier(privateKeyVerifier);","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/shared/zedAuth.js#L99-L135","documentation":"parseZedCallbackPayload tries to interpret the pasted Zed sign-in callback as JSON, then as an absolute URL, then as a bare query string (`?a=b`). If the input is not valid JSON and none of the URL constructions parse, it throws \"Invalid Zed callback URL\". This guards against users pasting truncated or malformed OAuth callback data when linking a Zed account.","triggerScenarios":"Calling parseZedCallbackPayload with a string that is neither valid JSON, a parseable URL, nor a bare query string — e.g. pasting only part of the callback URL, an HTML error page, or free text.","commonSituations":"User copies the callback URL but truncates it (missing scheme or query), pastes the sign-in page URL instead of the redirect, or the clipboard grabbed extra characters. Also happens when automation feeds the wrong payload (e.g. a state code only).","solutions":["Re-do the Zed sign-in flow and paste the FULL callback URL exactly as captured (including http://127.0.0.1:PORT/... and query string).","If you have raw params only, format them as a query string like `user_id=123&access_token=...` — the parser accepts a bare `?a=b` fragment.","Alternatively pass a JSON object string containing user_id and access_token keys.","Trim whitespace/newlines from the pasted value before calling; the function trims but inner invalid characters still break URL parsing."],"exampleFix":"// before\nparseZedCallbackPayload(\"user_id=42 access_token=abc\"); // space instead of &\n// after\nparseZedCallbackPayload(\"user_id=42&access_token=abc\");","handlingStrategy":"validation","validationCode":"function isValidZedCallbackInput(input) {\n  const raw = String(input || \"\").trim();\n  if (!raw) return false;\n  try { JSON.parse(raw); return true; } catch {}\n  try { new URL(raw); return true; } catch {}\n  try { new URL(`http://127.0.0.1/?${raw.replace(/^\\?/, \"\")}`); return true; } catch {}\n  return false;\n}\n// call before: if (!isValidZedCallbackInput(pasted)) prompt user to re-copy;\n","typeGuard":"const isNonEmptyString = (v) => typeof v === \"string\" && v.trim().length > 0;","tryCatchPattern":"try {\n  const { userId, encryptedAccessToken } = parseZedCallbackPayload(input);\n} catch (e) {\n  if (e.message === \"Invalid Zed callback URL\") {\n    // re-prompt user to paste the complete callback URL\n  } else throw e;\n}","preventionTips":["Prompt users to copy the entire redirect URL including scheme and query string.","Trim surrounding whitespace and quotes from pasted input before parsing.","Prefer building the payload as JSON ({user_id, access_token}) when capturing programmatically."],"tags":["validation","oauth","input-parsing"],"backgroundTag":"invalid-callback-url","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}