{"record":{"id":"f078d395e05a99c3","repo":"usebruno/bruno","slug":"response-error","errorCode":null,"errorMessage":"${response.error}","messagePattern":"\\$\\{response\\.error\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-electron/src/ipc/collection.js","lineNumber":2013,"sourceCode":"            processEnvVars,\n            promptVariables\n          });\n          let refreshRequestForConfig = { ...requestCopy, url: interpolatedRefreshUrl };\n          certsAndProxyConfigForRefreshUrl = await getCertsAndProxyConfig({\n            collectionUid,\n            collection,\n            request: refreshRequestForConfig,\n            envVars,\n            runtimeVariables,\n            processEnvVars,\n            collectionPath,\n            globalEnvironmentVariables\n          });\n        }\n\n        const handleOAuth2Response = (response) => {\n          if (response.error && !response.debugInfo) {\n            throw new Error(response.error);\n          }\n          return response;\n        };\n\n        switch (grantType) {\n          case 'authorization_code':\n            interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);\n            return await getOAuth2TokenUsingAuthorizationCode({\n              request: requestCopy,\n              collectionUid,\n              forceFetch: true,\n              certsAndProxyConfigForTokenUrl,\n              certsAndProxyConfigForRefreshUrl\n            }).then(handleOAuth2Response);\n\n          case 'client_credentials':\n            interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);\n            return await getOAuth2TokenUsingClientCredentials({","sourceCodeStart":1995,"sourceCodeEnd":2031,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-electron/src/ipc/collection.js#L1995-L2031","documentation":"Thrown by handleOAuth2Response inside the renderer:fetch-oauth2-credentials flow when the token endpoint response carries an `.error` field but no `.debugInfo`. This is a non-recoverable OAuth2 error surfaced from the identity provider (e.g. invalid_grant, invalid_client, bad_verification_code). Responses with debugInfo are passed through so callers can retry with diagnostics.","triggerScenarios":"Any OAuth2 grant (authorization_code, refresh_token, client_credentials, password) where the provider returns `{ error: '...' }` without a debug payload — typically expired codes, revoked refresh tokens, redirect URI mismatch, or wrong client credentials.","commonSituations":"Auth code used after expiry (10-minute window), refresh token revoked out-of-band, clock skew against the IdP, client secret rotated but not updated, redirect URI not whitelisted.","solutions":["Re-trigger the authorization_code flow — codes are single-use and short-lived.","Confirm clientId, clientSecret, and token URL match the IdP app registration.","Verify the redirect URI sent matches what is registered with the provider.","If using refresh_token, prompt the user to re-authenticate when the token has been revoked.","Read response.error verbatim — it is the IdP's RFC 6749 error code (e.g. invalid_grant)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"/** @typedef {{ error?: string, debugInfo?: unknown, access_token?: string }} OAuth2Response */\n/** @param {OAuth2Response} r @returns {r is { error: string }} */\nfunction isOAuth2ErrorResponse(r) {\n  return !!r && typeof r.error === 'string' && !r.debugInfo;\n}","tryCatchPattern":"try {\n  const token = await ipcRenderer.invoke('renderer:fetch-oauth2-credentials', { itemUid, request, collection });\n  return token;\n} catch (err) {\n  // err.message is the IdP's RFC 6749 error code (e.g. 'invalid_grant')\n  if (/invalid_grant|expired/.test(err.message)) {\n    // re-authenticate the user\n  } else if (/invalid_client/.test(err.message)) {\n    // surface a credentials-config error\n  }\n  throw err;\n}","preventionTips":["Refresh tokens before they expire; do not let the auth code sit beyond its lifetime.","Keep clientId, clientSecret, token URL, and redirect URI in lockstep with the IdP registration.","Sync the system clock (NTP) to avoid IdP clock-skew rejections.","Treat presence of `.debugInfo` as retryable; absence as terminal — surface accordingly."],"tags":["oauth2","auth","ipc","token","identity-provider"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}