{"record":{"id":"039357aa3dc92e36","repo":"arsduo/koala","slug":"invalid-arguments-to-initialize-an-uploadableio","errorCode":null,"errorMessage":"Invalid arguments to initialize an UploadableIO","messagePattern":"Invalid arguments to initialize an UploadableIO","errorType":"validation","errorClass":"Koala::KoalaError","httpStatus":null,"severity":"error","filePath":"lib/koala/http_service/uploadable_io.rb","lineNumber":17,"sourceCode":"require \"tempfile\"\n\nmodule Koala\n  module HTTPService\n    class UploadableIO\n      attr_reader :io_or_path, :content_type, :filename\n\n      def initialize(io_or_path_or_mixed, content_type = nil, filename = nil)\n        # see if we got the right inputs\n        parse_init_mixed_param io_or_path_or_mixed, content_type\n\n        # filename is used in the Ads API\n        # if it's provided, take precedence over the detected filename\n        # otherwise, fall back to a dummy name\n        @filename = filename || @filename || \"koala-io-file.dum\"\n\n        raise KoalaError.new(\"Invalid arguments to initialize an UploadableIO\") unless @io_or_path\n        raise KoalaError.new(\"Unable to determine MIME type for UploadableIO\") if !@content_type\n      end\n\n      def to_upload_io\n        UploadIO.new(@io_or_path, @content_type, @filename)\n      end\n\n      def to_file\n        @io_or_path.is_a?(String) ? File.open(@io_or_path) : @io_or_path\n      end\n\n      def self.binary_content?(content)\n        content.is_a?(UploadableIO) || DETECTION_STRATEGIES.detect {|method| send(method, content)}\n      end\n\n      private\n      DETECTION_STRATEGIES = [\n        :sinatra_param?,","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/arsduo/koala/blob/47d052063ef8b5644fb59e279da0b52687999f55/lib/koala/http_service/uploadable_io.rb#L1-L35","documentation":"Koala::HTTPService::UploadableIO wraps a media source for multipart upload. Its constructor tries five parse strategies in order — Rails ActionDispatch::Http::UploadedFile, a Sinatra-style {tempfile:, type:} hash, File/Tempfile, a String path, and any object responding to #read — and raises Koala::KoalaError ('Invalid arguments to initialize an UploadableIO') when none of them sets @io_or_path (lib/koala/http_service/uploadable_io.rb:17). The argument was nil or a type Koala cannot treat as a file. You normally hit it indirectly: put_picture/put_video forward their source into UploadableIO.","triggerScenarios":"api.put_picture(nil) or api.put_picture(params[:missing_file_key]); passing an Integer or arbitrary object; a Hash lacking :tempfile or :type (e.g. Sinatra params with string keys 'tempfile'/'type'); a Paperclip/CarrierWave uploader object instead of its underlying File or path.","commonSituations":"A Rails form rendered without the file field so params[:photo] is nil; attachment wrappers passed instead of the raw file; Sinatra params forwarded with string keys where the parser requires symbols; refactors that pass a filename variable that was never assigned.","solutions":["Pass a real media source: a path String, File/Tempfile, an IO-like object (StringIO), an ActionDispatch::Http::UploadedFile, or a Sinatra {tempfile:, type:} hash with symbol keys","Check the upload param for nil at the controller edge (raise 'choose a file') before calling put_picture","Unwrap ORM/attachment objects — give Koala the underlying File or path (e.g. uploader.file.file), not the uploader itself","In Sinatra, symbolize the file param hash keys before passing"],"exampleFix":"# before\napi.put_picture(params[:photo]) # params[:photo] is nil when no file was selected\n\n# after\nfile = params[:photo]\nraise 'Please choose a file' if file.nil?\napi.put_picture(file) # ActionDispatch::Http::UploadedFile is recognized natively","handlingStrategy":"validation","validationCode":"def uploadable_source?(obj)\n  obj.is_a?(String) || obj.is_a?(File) || obj.is_a?(Tempfile) || obj.respond_to?(:read) ||\n    (obj.respond_to?(:content_type) && obj.respond_to?(:tempfile)) || # Rails ActionDispatch::Http::UploadedFile\n    (obj.is_a?(Hash) && obj.key?(:tempfile) && obj.key?(:type))        # Sinatra param hash\nend\n\nraise ArgumentError, 'media must be a path, File, IO, or uploaded-file param' unless uploadable_source?(media)\napi.put_picture(media)","typeGuard":"def uploadable_source?(obj)\n  obj.is_a?(String) || obj.is_a?(File) || obj.is_a?(Tempfile) || obj.respond_to?(:read) ||\n    (obj.respond_to?(:content_type) && obj.respond_to?(:tempfile)) ||\n    (obj.is_a?(Hash) && obj.key?(:tempfile) && obj.key?(:type))\nend\n# uploadable_source?(params[:photo]) => true / false","tryCatchPattern":"begin\n  api.put_picture(media)\nrescue Koala::KoalaError => e\n  # raised before any HTTP traffic — the media argument shape is wrong\n  render json: {error: \"Unsupported file source: #{media.class}\"}, status: 400\nend","preventionTips":["Validate the upload param is present (non-nil) at the controller before calling put_picture/put_video","Pass primitive sources (path, File, StringIO) instead of framework or attachment wrappers","In Sinatra, pass the file param hash with symbol keys (:tempfile, :type)","Unit-test the upload path with every source type you support (path, File, StringIO, uploaded file)"],"tags":["file-upload","invalid-arguments","uploadable-io","facebook-graph-api"],"backgroundTag":"invalid-file-upload-argument","analyzedSha":"47d052063ef8b5644fb59e279da0b52687999f55","analyzedAt":"2026-08-23T10:19:03.891Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}