{"record":{"id":"40074148a60cb8b5","repo":"decolua/9router","slug":"no-json-found-in-decoded-code-400741","errorCode":null,"errorMessage":"\"No JSON found in decoded code\"","messagePattern":"\"No JSON found in decoded code\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"src/lib/oauth/providers/clinepass.js","lineNumber":22,"sourceCode":"  config: CLINEPASS_CONFIG,\n  flowType: \"authorization_code\",\n  buildAuthUrl: (config, redirectUri) => {\n    const params = new URLSearchParams({\n      client_type: \"extension\",\n      callback_url: redirectUri,\n      redirect_uri: redirectUri,\n    });\n    return `${config.authorizeUrl}?${params.toString()}`;\n  },\n  exchangeToken: async (config, code, redirectUri) => {\n    try {\n      // Cline encodes token data as base64 in the code param\n      let base64 = code;\n      const padding = 4 - (base64.length % 4);\n      if (padding !== 4) base64 += \"=\".repeat(padding);\n      const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n      const lastBrace = decoded.lastIndexOf(\"}\");\n      if (lastBrace === -1) throw new Error(\"No JSON found in decoded code\");\n      const tokenData = JSON.parse(decoded.substring(0, lastBrace + 1));\n      return {\n        access_token: tokenData.accessToken,\n        refresh_token: tokenData.refreshToken,\n        email: tokenData.email,\n        firstName: tokenData.firstName,\n        lastName: tokenData.lastName,\n        expires_at: tokenData.expiresAt,\n      };\n    } catch (e) {\n      const response = await fetch(config.tokenUrl, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\" },\n        body: JSON.stringify({ grant_type: \"authorization_code\", code, client_type: \"extension\", redirect_uri: redirectUri }),\n      });\n      if (!response.ok) {\n        const error = await response.text();\n        throw new Error(`ClinePass token exchange failed: ${error}`);","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/providers/clinepass.js#L4-L40","documentation":"clinepass.js duplicates cline.js's shortcut: it treats the callback `code` as base64-encoded JSON token data, decodes it, and throws this error when the decoded text contains no '}' (no JSON object). As in cline.js, this throw deliberately transfers control to the catch block that performs the real HTTP token exchange, so it is an internal control-flow signal rather than a user-facing failure.","triggerScenarios":"exchangeToken called with a plain authorization code, an empty string, or any non-base64-JSON value from the Cline Pass callback; also happens whenever Cline's current flow issues ordinary codes instead of encoded payloads.","commonSituations":"Cline Pass changing its callback payload format, manual testing with arbitrary code strings, double-URL-decoding corrupting the base64, or callbacks carrying error/none codes.","solutions":["Usually none: the catch block falls back to the HTTP token exchange automatically.","If the overall flow still fails, inspect the fallback exchange error (its message names the upstream cause).","Confirm the code param is passed through unmodified from Cline's redirect.","If the shortcut path is permanently dead upstream, remove or guard the base64 parse to avoid confusing logs."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"function clinePassCodeHasJson(code) {\n  if (typeof code !== 'string' || !code) return false;\n  let b = code;\n  const pad = 4 - (b.length % 4);\n  if (pad !== 4) b += '='.repeat(pad);\n  const decoded = Buffer.from(b, 'base64').toString('utf-8');\n  return decoded.includes('{') && decoded.lastIndexOf('}') !== -1;\n}\n// route directly to the HTTP path when this returns false","typeGuard":"function isBase64JsonObject(code) {\n  if (typeof code !== 'string') return false;\n  try {\n    const decoded = Buffer.from(code, 'base64').toString('utf-8');\n    return decoded.lastIndexOf('}') !== -1;\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  const tokens = await clinepass.exchangeToken(config, code, redirectUri);\n  // use tokens\n} catch (err) {\n  if (err.message === 'No JSON found in decoded code') {\n    // internal branch trigger — HTTP fallback already executed;\n    // seeing this thrown means the fallback also failed — inspect its error\n  }\n  throw err;\n}","preventionTips":["Expect this throw on every plain-code flow; it is the designed handoff to the HTTP exchange.","Match on the exact message string 'No JSON found in decoded code' if you branch on it.","Preserve the code param verbatim from the redirect (no extra decoding/trimming).","If the shortcut never succeeds in your environment, prefer calling the HTTP exchange directly to avoid noisy throws."],"tags":["oauth","cline","base64","fallback"],"backgroundTag":"no-json-in-decoded-code","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}