carrierwaveuploader/carrierwave · error · NotImplementedError

Need to implement #retrieve_from_cache! if you want to use #

Error message

Need to implement #retrieve_from_cache! if you want to use #{self.class.name} as a cache storage.

What it means

NotImplementedError raised by the retrieve_from_cache! stub on CarrierWave::Storage::Abstract. It fires when CarrierWave asks the cache storage to fetch a previously cached file — i.e. Uploader::Cache#retrieve_from_cache! (rehydrating the hidden cache field after a failed form submit) or cache_stored_file! before processing — and the active engine never implemented that method.

Source

Thrown at lib/carrierwave/storage/abstract.rb:31

        @uploader = uploader
      end

      def identifier
        uploader.deduplicated_filename
      end

      def store!(file)
      end

      def retrieve!(identifier)
      end

      def cache!(new_file)
        raise NotImplementedError, "Need to implement #cache! if you want to use #{self.class.name} as a cache storage."
      end

      def retrieve_from_cache!(identifier)
        raise NotImplementedError, "Need to implement #retrieve_from_cache! if you want to use #{self.class.name} as a cache storage."
      end

      def delete_dir!(path)
        raise NotImplementedError, "Need to implement #delete_dir! if you want to use #{self.class.name} as a cache storage."
      end

      def clean_cache!(seconds)
        raise NotImplementedError, "Need to implement #clean_cache! if you want to use #{self.class.name} as a cache storage."
      end
    end # Abstract
  end # Storage
end # CarrierWave

View on GitHub (pinned to b5f0abe10e)

Solutions

  1. Set config.cache_storage = :file (the default flow: cache on disk, store wherever)
  2. Implement #retrieve_from_cache!(identifier) in your Abstract storage subclass, symmetric with #cache!
  3. Upgrade CarrierWave if you rely on fog storage performing caching

Example fix

# before
class Storage::MyDb < CarrierWave::Storage::Abstract
  def cache!(file); @db.put(identifier, file.read); end # retrieve_from_cache! missing
end

# after
class Storage::MyDb < CarrierWave::Storage::Abstract
  def cache!(file); @db.put(identifier, file.read); end
  def retrieve_from_cache!(identifier)
    CacheFile.new(@db.get(identifier), identifier)
  end
end
Defensive patterns

Strategy: validation

Validate before calling

cache_engine = (MyUploader.cache_storage || MyUploader.storage)
raise "cache storage must implement #retrieve_from_cache!" unless cache_engine.instance_methods.include?(:retrieve_from_cache!)

Type guard

def cache_capable_storage?(klass)
  %i[cache! retrieve_from_cache! delete_dir! clean_cache!].all? { |m| klass.instance_methods.include?(m) }
end

Prevention

When it happens

Trigger: A custom or store-only storage engine resolving as cache storage (self.class.cache_storage || self.class.storage) while the app round-trips the cache param: uploader.retrieve_from_cache!(params[:image_cache]) in the re-display path, or processing a stored file which calls cache_stored_file!.

Common situations: Custom storage authors implementing cache! but forgetting retrieval; re-submitting a form after a validation error once the engine was swapped;CarrierWave versions where fog lacked cache methods.

Related errors


AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21). Data as JSON: /api/errors/e57b546bc2261f1d. Report an issue: GitHub.