{"record":{"id":"12ce9eda37b6574c","repo":"ToolJet/ToolJet","slug":"refresh-token-failed-12ce9e","errorCode":null,"errorMessage":"Refresh token failed","messagePattern":"Refresh token failed","errorType":"exception","errorClass":"QueryError","httpStatus":null,"severity":"error","filePath":"marketplace/plugins/microsoft_graph/lib/index.ts","lineNumber":419,"sourceCode":"    };\n\n    const headers = {\n      'Content-Type': 'application/x-www-form-urlencoded',\n    };\n\n    try {\n      const response = await got(tokenEndpoint, {\n        method: 'post',\n        headers,\n        form: tokenRequestBody,\n        responseType: 'json', // Automatically parse JSON response\n      });\n      const result = response.body;\n      if (result['access_token']) {\n        accessTokenDetails['access_token'] = result['access_token'];\n        accessTokenDetails['refresh_token'] = result['refresh_token'];\n      } else {\n        throw new QueryError('Refresh token failed', 'Access token not found in response', {});\n      }\n    } catch (error) {\n      throw new QueryError('Error while generating refresh access token', JSON.stringify(error), {});\n    }\n    return accessTokenDetails;\n  }\n}\n","sourceCodeStart":401,"sourceCodeEnd":427,"githubUrl":"https://github.com/ToolJet/ToolJet/blob/20602a8e101f2e59686c9afde0d1402aac2c8871/marketplace/plugins/microsoft_graph/lib/index.ts#L401-L427","documentation":"Thrown in refreshToken() at marketplace/plugins/microsoft_graph/lib/index.ts:419 when the token endpoint POST succeeded (got did not throw) but the parsed response body has no access_token. QueryError('Refresh token failed', 'Access token not found in response', {}). It indicates a 2xx response with an unexpected shape rather than an HTTP error. Note: because this throw sits inside the same try, it is normally re-caught at index.ts:421 and rewrapped as 'Error while generating refresh access token' (error 176).","triggerScenarios":"Microsoft returns 200 with an error object instead of a token (rare, conditional access or malformed grant handled gracefully by the endpoint); responseType:'json' parsed the body into an object lacking access_token; tenant endpoint returned an unexpected schema; intermediary (proxy) returning a 200 status page.","commonSituations":"A transparent proxy returning its own 200 HTML/JSON; Azure conditional access returning a challenge body; partial response due to network truncation parsed as valid JSON; tenant misconfiguration routing to a non-token endpoint.","solutions":["Log the full response body (the third arg of the resulting QueryError, once re-caught) to see what was returned instead of a token.","Verify the tokenEndpoint URL is correct for the tenant (https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token).","If a proxy is intercepting, exclude Microsoft login endpoints or configure got to bypass it.","Re-authenticate to obtain a fresh refresh_token and retry the exchange."],"exampleFix":"// before: no visibility into a 200-without-token response\nif (result['access_token']) { ... } else { throw new QueryError('Refresh token failed', 'Access token not found in response', {}); }\n\n// after: include the unexpected body in the error for diagnostics\nif (result['access_token']) { ... } else { throw new QueryError('Refresh token failed', 'Access token not found in response', { body: result }); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasAccessToken(body: unknown): body is { access_token: string; refresh_token?: string } {\n  return typeof (body as any)?.access_token === 'string' && (body as any).access_token.length > 0;\n}","tryCatchPattern":"import { QueryError } from '@tooljet-marketplace/common';\n\ntry {\n  await plugin.refreshToken(sourceOptions, dataSourceId, userId, isAppPublic);\n} catch (e) {\n  // error 175 is normally re-caught as 176; detect by description text\n  if (e instanceof QueryError && /Access token not found in response/i.test(String(e.description))) {\n    // inspect the response body captured in details, then re-authenticate\n  } else throw e;\n}","preventionTips":["Log the response body when access_token is missing to detect proxy/conditional-access interference.","Verify the token endpoint URL matches the tenant.","Bypass transparent proxies for login.microsoftonline.com.","Re-authenticate to obtain a fresh refresh_token if the exchange returns an unexpected body."],"tags":["microsoft-graph","oauth","refresh-token","unexpected-response","tooljet"],"backgroundTag":null,"analyzedSha":"20602a8e101f2e59686c9afde0d1402aac2c8871","analyzedAt":"2026-08-13T05:58:54.221Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}