{"record":{"id":"893e1f3672e2b643","repo":"ruvnet/ruflo","slug":"token-refresh-failed-response-status","errorCode":null,"errorMessage":"Token refresh failed: ${response.status}","messagePattern":"Token refresh failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/mcp/src/oauth.ts","lineNumber":244,"sourceCode":"\n    if (this.config.clientSecret) {\n      params.set('client_secret', this.config.clientSecret);\n    }\n\n    const response = await fetch(this.config.tokenEndpoint, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n      body: params.toString(),\n    });\n\n    if (!response.ok) {\n      const error = await response.text();\n      this.logger.error('Token refresh failed', { status: response.status, error });\n      // Clear invalid tokens\n      await this.tokenStorage.delete(storageKey);\n      throw new Error(`Token refresh failed: ${response.status}`);\n    }\n\n    const data = (await response.json()) as TokenResponse;\n    const tokens = this.parseTokenResponse(data);\n\n    // Preserve refresh token if not returned in response\n    if (!tokens.refreshToken && existing.refreshToken) {\n      tokens.refreshToken = existing.refreshToken;\n    }\n\n    await this.tokenStorage.save(storageKey, tokens);\n    this.logger.info('Token refresh successful');\n    this.emit('tokens:refreshed', { expiresIn: tokens.expiresIn });\n\n    return tokens;\n  }\n\n  /**","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/mcp/src/oauth.ts#L226-L262","documentation":"The token endpoint returned a non-2xx status for the refresh grant. The failed stored tokens are deleted (so stale credentials can't loop) and the HTTP status is surfaced — invalid/expired refresh token, revoked grant, or endpoint outage.","triggerScenarios":"Thrown at v3/@claude-flow/mcp/src/oauth.ts:244 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the status: 400/401 usually means the refresh token was revoked or expired; redo the login flow.","Verify client_id/client_secret and token endpoint match the OAuth app configuration."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}