{"record":{"id":"f6a107a3ac7da926","repo":"arsduo/koala","slug":"generate-client-code-received-an-error-empty-resp","errorCode":null,"errorMessage":"generate_client_code received an error: empty response body","messagePattern":"generate_client_code received an error: empty response body","errorType":"exception","errorClass":"Koala::Facebook::BadFacebookResponse","httpStatus":200,"severity":"error","filePath":"lib/koala/oauth.rb","lineNumber":135,"sourceCode":"      # access token from Facebook. After which the clients can use that access token to make\n      # requests to Facebook without having to use the server token, yet the server access token\n      # remains valid.\n      # See https://developers.facebook.com/docs/facebook-login/access-tokens/#long-via-code\n      #\n      # @param access_token a user's long lived (server) access token\n      #\n      # @raise Koala::Facebook::ServerError if Facebook returns a server error (status >= 500)\n      # @raise Koala::Facebook::OAuthTokenRequestError if Facebook returns an error response (status >= 400)\n      # @raise Koala::Facebook::BadFacebookResponse if Facebook returns a blank response\n      # @raise Koala::KoalaError if response does not contain 'code' hash key\n      #\n      # @return a string of the generated 'code'\n      def generate_client_code(access_token)\n        response = fetch_token_string({:redirect_uri => @oauth_callback_url, :access_token => access_token}, false, 'client_code')\n\n        # Facebook returns an empty body in certain error conditions\n        if response == ''\n          raise BadFacebookResponse.new(200, '', 'generate_client_code received an error: empty response body')\n        else\n          result = JSON.parse(response)\n        end\n\n        result.has_key?('code') ? result['code'] : raise(Koala::KoalaError.new(\"Facebook returned a valid response without the expected 'code' in the body (response = #{response})\"))\n      end\n\n      # access tokens\n\n      # Fetches an access token, token expiration, and other info from Facebook.\n      # Useful when you've received an OAuth code using the server-side authentication process.\n      # @see url_for_oauth_code\n      #\n      # @note (see #url_for_oauth_code)\n      #\n      # @param code (see #url_for_access_token)\n      # @param options any additional parameters to send to Facebook when redeeming the token\n      #","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/arsduo/koala/blob/47d052063ef8b5644fb59e279da0b52687999f55/lib/koala/oauth.rb#L117-L153","documentation":"Koala::Facebook::BadFacebookResponse (a subclass of APIError) is raised by OAuth#generate_client_code when its GET /oauth/client_code call (client_id, client_secret, redirect_uri, access_token, always over SSL through fetch_token_string) returns HTTP 200 with a completely empty body. Facebook uses an empty 200 body instead of a JSON error for several failure modes on this endpoint, so Koala cannot extract an error code and surfaces the raw condition; the exception carries http_status 200 and an empty response_body.","triggerScenarios":"Calling @oauth.generate_client_code(access_token) where the token is expired or invalid, is a short-lived client token rather than the long-lived server token, or was issued for a different app; or where the redirect_uri Koala sends (taken from @oauth_callback_url, the third OAuth.new argument) does not exactly match a Valid OAuth Redirect URI configured in the Facebook app dashboard. Facebook accepts the request with 200, returns a zero-length body, and line 134 converts that into this exception.","commonSituations":"Dev and production credential mixups (wrong secret or callback URL per environment); forgetting to extend the short-lived token with exchange_access_token before requesting a client code; trailing-slash or http-vs-https differences between the configured callback and the app dashboard; occasional transient Facebook-side empty responses.","solutions":["Verify the access token is a valid long-lived user token: exchange it first with @oauth.exchange_access_token(token) and feed the returned token to generate_client_code.","Make the callback URL passed as the third argument to Koala::Facebook::OAuth.new exactly match a Valid OAuth Redirect URI in the Facebook app dashboard (scheme, host, path, trailing slash).","Confirm the app_id and app_secret belong to the same app that issued the token; check for dev and prod app mixups.","Retry once after a short delay to rule out a transient Facebook-side empty response.","Enable Koala::Utils.logger or Faraday logging to capture the exact /oauth/client_code request and response."],"exampleFix":"// before\n@oauth = Koala::Facebook::OAuth.new(APP_ID, APP_SECRET)\ncode = @oauth.generate_client_code(token)\n\n// after\n@oauth = Koala::Facebook::OAuth.new(APP_ID, APP_SECRET, \"https://example.com/auth/callback\")\nlong_lived = @oauth.exchange_access_token(token)\nbegin\n  code = @oauth.generate_client_code(long_lived)\nrescue Koala::Facebook::BadFacebookResponse => e\n  Rails.logger.warn(\"client_code failed: #{e.message}\")\n  code = nil\nend","handlingStrategy":"try-catch","validationCode":"raise ArgumentError, \"oauth callback URL must be configured\" unless @oauth.oauth_callback_url.to_s.start_with?(\"https://\")\nraise ArgumentError, \"token does not look long-lived\" if token.to_s.length < 100","typeGuard":"def long_lived_server_token?(token)\n  token.is_a?(String) && token.length > 100 # long-lived tokens are roughly 200 chars\nend","tryCatchPattern":"begin\n  code = @oauth.generate_client_code(token)\nrescue Koala::Facebook::BadFacebookResponse => e\n  # HTTP 200 with empty body: suspect token validity or redirect_uri mismatch\n  Rails.logger.warn(\"client_code rejected: #{e.message}\")\n  code = nil\nend","preventionTips":["Extend tokens to long-lived with exchange_access_token before generating a client code; only server tokens qualify","Keep one configured callback URL used for both url_for_oauth_code and generate_client_code so redirect_uri always matches","Separate dev and prod app credentials per environment so tokens are never redeemed against the wrong app"],"tags":["oauth","facebook","koala","empty-response","access-token","client-code"],"backgroundTag":"empty-api-response","analyzedSha":"47d052063ef8b5644fb59e279da0b52687999f55","analyzedAt":"2026-08-23T10:19:03.891Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}