{"record":{"id":"57933844fc4eb7b7","repo":"decolua/9router","slug":"this-request-isn-t-valid-please-restart-the-kimch","errorCode":null,"errorMessage":"This request isn't valid. Please restart the Kimchi login flow.","messagePattern":"This request isn't valid\\. Please restart the Kimchi login flow\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lib/oauth/services/kimchi.js","lineNumber":79,"sourceCode":"      s.done = true;\n      s.resolved = r;\n      clearTimeout(s.timeout);\n      try { s.close(); } catch { /* already closed */ }\n      setTimeout(() => sessions.delete(state), SESSION_TTL_MS).unref?.();\n    });\n\n    const callbackUrl = `http://127.0.0.1:${port}${KIMCHI_CONFIG.callbackPath}`;\n    const authUrl = buildKimchiAuthUrl(callbackUrl, state);\n    return { authUrl, port, state, result, close };\n  }\n\n  async _handleCallback(params, expectedState) {\n    if (params.error) {\n      throw new Error(params.error_description || params.error);\n    }\n    const candidate = params.state;\n    if (!candidate || candidate !== expectedState) {\n      throw new Error(\"This request isn't valid. Please restart the Kimchi login flow.\");\n    }\n    const token = params.token;\n    if (!token) {\n      throw new Error(\"No token was returned by the Kimchi authentication server\");\n    }\n    const check = await this.validateToken(token);\n    if (!check.valid) {\n      throw new Error(check.error || \"Kimchi token validation failed\");\n    }\n    return { token };\n  }\n\n  async fetchProfile(token) {\n    try {\n      const res = await fetch(KIMCHI_CONFIG.meUrl, {\n        headers: { Authorization: `Bearer ${token}` },\n      });\n      if (!res.ok) return {};","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/services/kimchi.js#L61-L97","documentation":"Thrown by KimchiService._handleCallback() when the `state` query parameter is missing or does not equal the random state generated at startLogin(). State is the CSRF protection binding the callback to a specific in-flight session; a mismatch means the callback cannot be trusted to belong to this login attempt. The error instructs restarting the flow.","triggerScenarios":"A callback arrives at the local server whose `state` param differs from the expectedState captured in the closure — the user reloaded an old auth tab from a previous attempt, hit the callback URL manually, completed two concurrent logins whose callbacks crossed (old tab completing after the new session started), or a scanner/prefetch hit 127.0.0.1:<port> with no/garbage params.","commonSituations":"Reusing a stale browser tab from a prior login attempt while a new one is pending; running two `kimchi login` flows simultaneously; antivirus or security software probing the localhost port; session map entries crossed after rapid retry.","solutions":["Restart the login: run the Kimchi login command again and use only the freshly opened browser tab.","Close all older Kimchi auth tabs before starting a new flow.","Avoid running two Kimchi logins concurrently — finish or cancel one before the other.","If a tool/AV probes localhost ports, exclude 127.0.0.1 callback ports from scanning."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// Validate state before treating a callback as authentic\nfunction hasValidState(params, expectedState) {\n  return params != null && typeof params.state === \"string\" && params.state === expectedState;\n}","typeGuard":"function isTrustedCallback(p, expected) {\n  return typeof p === \"object\" && p !== null && typeof p.state === \"string\" && p.state === expected;\n}","tryCatchPattern":"try {\n  const outcome = await session.result;\n  if (outcome.error === \"This request isn't valid. Please restart the Kimchi login flow.\") {\n    console.error(\"State mismatch — a stale tab or foreign request hit the callback. Start a new login.\");\n  }\n} catch { /* startLogin resolves errors into the result object */ }","preventionTips":["Use only the browser tab opened by the current login attempt; close all older auth tabs.","Never run concurrent Kimchi logins — each generates its own state and port.","Never hand-craft or replay callback URLs.","Note _handleCallback errors are resolved (not rejected) into the session result as { error } — check outcome.error."],"tags":["oauth","csrf","state-mismatch","kimchi"],"backgroundTag":"oauth-state-mismatch","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}