{"record":{"id":"6590a91976f6321e","repo":"pot-app/pot-desktop","slug":"can-not-find-access-token-json-stringify-result","errorCode":null,"errorMessage":"Can not find access_token: ${JSON.stringify(result)}","messagePattern":"Can not find access_token: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/window/Config/pages/Backup/utils/aliyun.jsx","lineNumber":176,"sourceCode":"            throw new Error(`Get UserInfo Error: ${JSON.stringify(result)}`);\n        }\n    }\n}\n\nexport async function accessToken(code) {\n    const res = await fetch('https://pot-app.com/api/ali_access_token', {\n        method: 'POST',\n        body: Body.json({\n            code,\n            refresh_token: '',\n        }),\n    });\n    if (res.ok) {\n        const result = res.data;\n        if (result['access_token']) {\n            return result['access_token'];\n        } else {\n            throw new Error(`Can not find access_token: ${JSON.stringify(result)}`);\n        }\n    } else {\n        const result = res.data;\n        if (result['message']) {\n            throw new Error(result['message']);\n        } else {\n            throw new Error(`Get accessToken Error: ${JSON.stringify(result)}`);\n        }\n    }\n}\n\nasync function driveId(token) {\n    const res = await fetch('https://openapi.alipan.com/adrive/v1.0/user/getDriveInfo', {\n        method: 'POST',\n        headers: {\n            Authorization: `Bearer ${token}`,\n        },\n    });","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/pot-app/pot-desktop/blob/594d32ede96acd106b0256deaa8bb440ffcdff40/src/window/Config/pages/Backup/utils/aliyun.jsx#L158-L194","documentation":"The accessToken() helper exchanges the OAuth auth code via https://pot-app.com/api/ali_access_token and expects `access_token` in a 200 response. If it's missing, it throws `Can not find access_token: <body JSON>` — the exchange endpoint returned 200 but not the token payload.","triggerScenarios":"Calling accessToken(code) with an HTTP 200 whose res.data lacks `access_token` — e.g. the auth code was already redeemed/expired and the pot-app backend returned a JSON error object with 200, or its response schema changed.","commonSituations":"Reusing an authCode that Alipan allows only once (single-use codes); the code expired between the QR scan and the exchange; the pot-app relay API changing shape or being down while still returning 200 with an error body.","solutions":["Inspect the JSON dump for an embedded error describing why the exchange failed.","Restart the whole QR login flow to get a fresh authCode — codes are single-use and short-lived.","Exchange the code immediately after scanning; do not cache or retry with the same code.","Verify the pot-app.com relay API is up and still returns `access_token` (consider using Alipan's token endpoint directly if it changed)."],"exampleFix":"// before\nif (result['access_token']) {\n    return result['access_token'];\n} else {\n    throw new Error(`Can not find access_token: ${JSON.stringify(result)}`);\n}\n// after\nif (result && typeof result.access_token === 'string') {\n    return result.access_token;\n}\nconsole.error('token exchange failed', result);\nthrow new Error('Auth code invalid or already used — restart QR login to get a new code');","handlingStrategy":"validation","validationCode":"// validate the auth code shape before exchanging, and exchange immediately after scan\nfunction looksLikeAuthCode(code) {\n  return typeof code === 'string' && code.length > 10;\n}\nif (!looksLikeAuthCode(code)) throw new Error('Invalid authCode — restart QR login');","typeGuard":"function hasAccessToken(r) {\n  return r && typeof r === 'object' && typeof r.access_token === 'string' && r.access_token.length > 0;\n}","tryCatchPattern":"try {\n  const token = await accessToken(code);\n} catch (e) {\n  if (String(e.message).startsWith('Can not find access_token')) {\n    // code single-use/expired — never retry same code\n    const { url, sid: newSid } = await qrcode();\n    promptUserToRescan(url, newSid);\n  } else {\n    showError(e.message);\n  }\n}","preventionTips":["Exchange the authCode immediately after the QR scan — codes are single-use and short-lived","Never retry the exchange with the same code after a failure","Inspect the 200-body JSON for embedded error details when the token is missing","Have a fallback to Alipan's direct token endpoint if the pot-app relay changes or fails"],"tags":["oauth","token-exchange","auth-code","alipan"],"backgroundTag":"oauth-authorization-code-invalid","analyzedSha":"594d32ede96acd106b0256deaa8bb440ffcdff40","analyzedAt":"2026-09-02T18:12:21.811Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}