arsduo/koala · error · Koala::KoalaError

Wrong number of arguments for put_#{method == "photos" ? "pi

Error message

Wrong number of arguments for put_#{method == "photos" ? "picture" : "video"}

What it means

put_picture and put_video accept flexible positional arguments and normalize them in parse_media_args; it raises Koala::KoalaError ('Wrong number of arguments for put_picture' or '...put_video') when the splat holds fewer than 1 or more than 5 values (lib/koala/api/graph_api_methods.rb:473). The media source is mandatory; the parser understands at most five positions (source, optional content_type, args hash, target id, options). Since put_picture(*picture_args) has no required parameter, even a zero-argument call reaches this raise.

Source

Thrown at lib/koala/api/graph_api_methods.rb:473

      #
      # @return an array of results from your batch calls (as if you'd made them individually),
      #         arranged in the same order they're made.
      def batch(http_options = {}, &block)
        batch_client = GraphBatchAPI.new(self)
        if block
          yield batch_client
          batch_client.execute(http_options)
        else
          batch_client
        end
      end

      private

      def parse_media_args(media_args, method)
        # photo and video uploads can accept different types of arguments (see above)
        # so here, we parse the arguments into a form directly usable in put_connections
        raise KoalaError.new("Wrong number of arguments for put_#{method == "photos" ? "picture" : "video"}") unless media_args.size.between?(1, 5)

        args_offset = media_args[1].kind_of?(Hash) || media_args.size == 1 ? 0 : 1

        args      = media_args[1 + args_offset] || {}
        target_id = media_args[2 + args_offset] || "me"
        options   = media_args[3 + args_offset] || {}

        if url?(media_args.first)
          # If media_args is a URL, we can upload without UploadableIO
          # Video: https://developers.facebook.com/docs/graph-api/video-uploads
          fb_expected_arg_name = method == "photos" ? :url : :file_url
          args.merge!(fb_expected_arg_name => media_args.first)
        else
          args["source"] = Koala::HTTPService::UploadableIO.new(*media_args.slice(0, 1 + args_offset))
        end

        [target_id, method, args, options]
      end

View on GitHub (pinned to 47d052063e)

Solutions

  1. Always pass the media source as the first argument: api.put_picture(source)
  2. When splatting dynamic arrays, compact and bounds-check first: raise unless media.compact.size.between?(1, 5)
  3. Use the documented positional forms instead of long chains: put_picture(file, content_type, args, target_id) already fits within the limit
  4. If the source may be missing, default it explicitly (source || fallback_path) instead of forwarding nils

Example fix

# before
media = [] # form posted without a file
api.put_picture(*media) # => KoalaError: Wrong number of arguments for put_picture

# after
media = [params[:file], params[:message] ? {message: params[:message]} : {}, params[:id] || 'me']
raise 'Please choose a file' if media[0].nil?
api.put_picture(*media)
Defensive patterns

Strategy: validation

Validate before calling

def valid_media_args?(media_args)
  media_args.size.between?(1, 5)
end

raise ArgumentError, 'put_picture/put_video need 1-5 arguments (source first)' unless valid_media_args?(media)
api.put_picture(*media)

Try / catch

begin
  api.put_picture(*media)
rescue Koala::KoalaError => e
  # argument-shape failure raised before any HTTP traffic — fix the call site; retrying cannot help
  logger.error("put_picture received #{media.size} args: #{media.inspect}")
  raise
end

Prevention

When it happens

Trigger: api.put_picture with an empty argument list (params-driven code where the media argument was nil-stripped or the form carried no file), or a dynamically splatted array with six or more elements: api.put_picture(*[src, type, args, id, opts, extra]).

Common situations: Controller code forwarding params: api.put_picture(*media) where media is built dynamically and turns out empty; refactors that change put_picture's positional signature; code passing every optional argument positionally, placeholders included, past the five-slot maximum.

Related errors


AI-assisted analysis of arsduo/koala@47d052063e (2026-08-23). Data as JSON: /api/errors/466e0cbb61c135e3. Report an issue: GitHub.