Skip to content

Separate named uploads from custom fields to avoid File objects in params.fields #88

Closed

Description

@kvz

The published transloadit 4.0.0 gem uses Assembly’s fields option for two different channels: custom fields in signed JSON and named multipart uploads. Passing a File through this option uploads the bytes correctly, but also serializes the File’s Ruby object representation into params.fields. Passing typed metadata through the same option duplicates it as form fields, where the encoder converts values to strings or bracketed form keys.

This came up while validating generated Ruby demos in https://github.com/transloadit/content/pull/6814, following https://github.com/transloadit/content/issues/6801.

Reproduce with Ruby >=3.1 and gem install transloadit --version 4.0.0 --no-document. This uses the real gem and its multipart encoder, with only Faraday’s final HTTP adapter replaced; no network request is made:

gem 'transloadit', '4.0.0'
require 'transloadit'
require 'faraday'
require 'tempfile'

class CaptureFields < Faraday::Adapter
  def call(env)
    super
    bytes = env.body.respond_to?(:read) ? env.body.read : env.body
    puts env.request_headers.fetch('Content-Type')
    puts bytes
    save_response(env, 200, JSON.generate({'ok' => 'ASSEMBLY_COMPLETED'}), {})
    @app.call(env)
  end
end
Faraday.default_adapter = CaptureFields
client = Transloadit.new(key: 'placeholder', secret: 'placeholder')
client.assembly(fields: {count: 2, enabled: false, details: {caption: 'kept'}}).create!
Tempfile.create('sdk-fields') do |file|
  file.binmode
  file.write("upload bytes")
  file.rewind
  client.assembly(fields: {file: file}).create!
end

Observed:

  • The first POST includes typed params.fields and top-level form entries count=2, enabled=false, details[caption]=kept.
  • The second POST includes a multipart file named file, and signed JSON resembling "fields":{"file":"#<File:0x...>"}. The File object text is not user metadata and varies between processes.

The duplication follows directly from Assembly#create!, which copies options[:fields] into extra_params, while Assembly#to_hash retains the same option in the JSON Instructions. ApiModel#_do_request then combines both channels before Request#to_payload builds the wire body.

Expected: a supported way to send named upload IOs without including them in params.fields, and to send typed custom fields once, retaining JSON number/boolean/array/object types. An explicit named-upload API would avoid overloading the metadata option and could preserve existing positional file_N behavior.

Current Content compatibility handling for pinned 4.0.0 is explicit: use the Assembly fields option for named File uploads, and supply actual custom metadata through create!(fields: metadata) so the JSON override removes the File representations. No SDK methods or serializers are patched. The Content sweep checks the actual encoded body, including exact JSON types and absence of duplicate metadata form fields. This issue tracks the SDK limitation behind that two-channel calling convention.

🤖 Claimed by kvz on framework1/ruby-sdk since 2026-10-18 · resume: codex resume 01a14e1d-ce02-76b1-81f0-5014b90ba94d

Activity

  1. self-assigned this
    on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions