carrierwaveuploader/carrierwave · error · CarrierWave::InvalidParameter
invalid cache id
Error message
invalid cache id
What it means
Raised as CarrierWave::InvalidParameter by Uploader::Cache#cache_id= when the cache id portion of a cache name does not match /\A(-)?\d+-\d+(-\d{4})?-\d{4}\z/. CarrierWave cache names look like 'TIMEINT-PID-COUNTER-RND/filename.ext' (the regex also tolerates the older 3-part format); anything else is rejected before the cache storage is touched, as an anti-tampering measure on the hidden cache form field.
Source
Thrown at lib/carrierwave/uploader/cache.rb:204
File.join(*[cache_dir, @cache_id, for_file].compact)
end
protected
attr_reader :cache_id
private
def workfile_path(for_file=original_filename)
File.join(CarrierWave.tmp_path, @cache_id, version_name.to_s, for_file)
end
attr_reader :original_filename
def cache_id=(cache_id)
# Earlier version used 3 part cache_id. Thus we should allow for
# the cache_id to have both 3 part and 4 part formats.
raise CarrierWave::InvalidParameter, "invalid cache id" unless cache_id =~ /\A(-)?[\d]+\-[\d]+(\-[\d]{4})?\-[\d]{4}\z/
@cache_id = cache_id
end
def original_filename=(filename)
raise CarrierWave::InvalidParameter, "invalid filename" if filename =~ CarrierWave::SanitizedFile.sanitize_regexp
@original_filename = filename
end
def cache_storage
@cache_storage ||= (self.class.cache_storage || self.class.storage).new(self)
end
# We can override the full_original_filename method in other modules
def full_original_filename
forcing_extension(original_filename)
end
end # Cache
end # UploaderView on GitHub (pinned to b5f0abe10e)
Solutions
- Validate the cache param against the expected pattern before calling retrieve_from_cache!
- Check the form: the hidden field must carry the exact uploader.cache_name value (use the provided form helpers so the round-trip is automatic)
- Rescue CarrierWave::InvalidParameter and treat it as a fresh upload instead of crashing
- Regenerate the cache value by re-uploading if the id came from a different CarrierWave version
Example fix
# before
uploader.retrieve_from_cache!(params[:image_cache]) # tampered value -> InvalidParameter
# after
CACHE_ID = /\A-?\d+-\d+(-\d{4})?-\d{4}\z/.freeze
cache_name = params[:image_cache].to_s
if cache_name.split('/', 2).first =~ CACHE_ID
uploader.retrieve_from_cache!(cache_name)
else
uploader.cache!(params[:image]) # fall back to the fresh upload
end Defensive patterns
Strategy: validation
Validate before calling
CACHE_NAME = /\A(-?\d+-\d+(-\d{4})?-\d{4})\/[^\/]+\z/.freeze
def valid_cache_name?(name)
name.to_s.match?(CACHE_NAME)
end
uploader.retrieve_from_cache!(cache_name) if valid_cache_name?(params[:image_cache]) Type guard
def cache_param?(value) value.is_a?(String) && value.match?(CACHE_NAME) end
Try / catch
begin uploader.retrieve_from_cache!(params[:image_cache]) rescue CarrierWave::InvalidParameter uploader.cache!(params[:image]) # treat as a fresh upload end
Prevention
- Always render the hidden cache field with the uploader-provided cache_name value (keep_the_cache / form helpers), never rebuild it in JS
- Regex-check the cache param (id segment: optional -, digits, digits, optional 4-digit, 4-digit) before retrieve_from_cache!
- Rescue CarrierWave::InvalidParameter and degrade gracefully to a fresh upload instead of a 500
When it happens
Trigger: uploader.retrieve_from_cache!(params[:image_cache]) where the submitted value was truncated, edited, or is a different field entirely: passing the filename alone, passing the full 'cache_id/filename' with a malformed id segment (letters where digits belong, missing parts), or an attacker probing the cache param.
Common situations: Re-rendering a form after validation errors where the hidden field name no longer matches params (e.g. nested attributes, form renaming); copy-pasting cache values between environments; manual curl posts omitting the id pieces; cache ids generated by a newer/older CarrierWave than the one re-reading them.
Related errors
- invalid filename
- Need to implement #cache! if you want to use #{self.class.na
- Need to implement #retrieve_from_cache! if you want to use #
- Need to implement #delete_dir! if you want to use #{self.cla
- Need to implement #clean_cache! if you want to use #{self.cl
AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21).
Data as JSON: /api/errors/80e74ceab2e3708d.
Report an issue: GitHub.