Derivatives seems to be losing the uploaded file

This feature was working once, and I just got alerted by the client that it has stopped working. As far as I can tell, nothing has changed in this code in quite a while, so I’m confused whether it ever worked, or something changed.

Here’s an attempt to upload an image:

Started POST "/ckeditor/pictures?&responseType=json" for at 2020-09-22 19:07:28 +0000
Processing by Ckeditor::PicturesController#create as */*
  Parameters: {"upload"=>#<ActionDispatch::Http::UploadedFile:0x000055d8d88e3620 @tempfile=#<Tempfile:/tmp/RackMultipart20200922-22723-11rsztq.jpg>, @original_filename="Amagi200.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"upload\"; filename=\"Amagi200.jpg\"\r\nContent-Type: image/jpeg\r\n">, "ckCsrfToken"=>"dGHmsNCMmyP6O70viLj8129kRGSr4E7Q5NM1Glxy", "responseType"=>"json"}
Completed 500 Internal Server Error in 525ms (ActiveRecord: 3.4ms | Allocations: 5314)
Shrine::InvalidFile (#<ImageProcessing::Builder:0x000055d8d9697b90 @options={:source=>#<Tempfile: (closed)>, :loader=>{}, :saver=>{}, :format=>nil, :operations=>[[:resize_to_limit, [800, 800]]], :processor=>ImageProcessing::MiniMagick::Processor}> is not a valid IO object (it doesn't respond to #read, #eof?, #rewind, #close)):
config/initializers/ckeditor_shrine.rb:41:in `promote'

The Picture class is defined thusly:

module Ckeditor
  class PictureUploader < Shrine
    plugin :determine_mime_type
    plugin :validation_helpers
    plugin :derivatives, versions_compatibility: true

    Attacher.validate do
      validate_mime_type_inclusion %w[image/jpeg image/gif image/png]
      validate_max_size 2.megabytes
    Attacher.derivatives_processor do |original|
      magick = SHRINE_PICTURE_PROCESSOR.source(original)
        content: magick.resize_to_limit(800, 800),
        thumb:   magick.resize_to_limit(118, 100),

  class Picture < Ckeditor::Asset
    include PictureUploader.attachment(:data)

    validates :data, presence: true

    def url_content

    def url_thumb

    def path

    def datasource
      @datasource ||= HashWithIndifferentAccess
                      .fetch(:thumb, {}))

And configured thusly:

# frozen_string_literal: true

require 'shrine'
# require 'shrine/storage/file_system'
require 'shrine/storage/s3'
require 'ckeditor/backend/shrine'

# Choose your favorite image processor
require 'image_processing/mini_magick'
SHRINE_PICTURE_PROCESSOR = ImageProcessing::MiniMagick

s3_props = { public: true,
  bucket: 'bucket-name',
  region: 'us-east-2',
  access_key_id: 'REDACTED',
  secret_access_key: 'REDACTED' 

Shrine.storages = {
  cache: prefix: 'subfolder/cache', **s3_props),
  store: prefix: 'subfolder/store', **s3_props),

Shrine.plugin :determine_mime_type
Shrine.plugin :activerecord
Shrine.plugin :instrumentation

Shrine.plugin :validation_helpers
Shrine.plugin :derivatives, versions_compatibility: true

class Shrine::Attacher
  def promote(*)

The last change I made was to update from the versions plugin to the new derivatives plugin, and everything was tested and working after that change.

Can you see any obvious mistakes here? I’m baffled how it could be losing the file between the initial upload (where you can see it has the file) and the initial resize, where it seems to be trying to resize a closed Tempfile.

The entire CKEditor/Shrine combo comes from here:

Here’s the TL;DR of what I’ve added to the original Gem:

Thanks in advance,


Hi Walter, you forgot to add the ! to #resize_to_limit calls to tell ImageProcessing you want to execute the pipeline. Without !, ImageProcessing returns an ImageProcessing::Builder for chaining additional processing methods, and no processing is executed yet at that point. This must have changed since you last tested it, because ImageProcessing worked like this since version 1.0.

Thanks, Janko! The mystery gets deeper. Once I cleared that hurdle, my server complained that I didn’t have ImageMagick installed. And yet this used to work. WTF!

All better, now.