rails icon indicating copy to clipboard operation
rails copied to clipboard

Multiple fileupload error: Invalid request parameters: expected Array (got String) for param

Open zebleck opened this issue 1 year ago • 2 comments

Steps to reproduce

Create a form with file_field to upload multiple files.

<%= form_with model: submission do |f| %> <%= f.file_field :manuscript, class: 'form-control-file', id: 'upload-userManuscript', multiple: true, accept: assignment.accepted_for_file_input %> <% end %>

Try to submit this form after selecting a file. Instead of just submitting the file as parameter, there will be an empty parameter added, which causes this error.

image

The file_field adds an empty input field that causes this parameter to be added in the form: image

This does not happen when the "multiple" option is set to false or when using Rails 6.

Expected behavior

Submit request should be executed normally (status code 200)

Actual behavior

Submit request causes an error (status code 400). See below for trace.

System configuration

Rails version: 7.0.2.3

Ruby version: 3.1.2

Full trace:

ActionController::BadRequest Invalid request parameters: expected Array (got String) for param `manuscript' Extracted source (around line #104):

#102 elsif after == "[]" #103 params[k] ||= [] *104 raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) #105 params[k] << v #106 elsif after =~ %r(^[][([^[]]+)]$) || after =~ %r(^[](.+)$) #107 child_key = $1

Extracted source (around line #118):

#116 params[k] ||= make_params #117 raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k]) *118 params[k] = normalize_params(params[k], after, v, depth - 1) #119 end #120 #121 params

Extracted source (around line #195):

#193 part.get_data do |data| #194 tag_multipart_encoding(part.filename, part.content_type, part.name, data) *195 @query_parser.normalize_params(@params, part.name, data, @query_parser.param_depth_limit) #196 end #197 end #198 MultipartInfo.new @params.to_params_hash, @collector.find_all(&:file?).map(&:body)

Rails.root: /usr/src/app

Framework Trace rack (2.2.3) lib/rack/query_parser.rb:104:in normalize_params' rack (2.2.3) lib/rack/query_parser.rb:118:in normalize_params' rack (2.2.3) lib/rack/multipart/parser.rb:195:in block (2 levels) in result' rack (2.2.3) lib/rack/multipart/parser.rb:104:in get_data' rack (2.2.3) lib/rack/multipart/parser.rb:193:in block in result' rack (2.2.3) lib/rack/multipart/parser.rb:127:in block in each' rack (2.2.3) lib/rack/multipart/parser.rb:127:in each' rack (2.2.3) lib/rack/multipart/parser.rb:127:in each' rack (2.2.3) lib/rack/multipart/parser.rb:192:in result' rack (2.2.3) lib/rack/multipart/parser.rb:81:in parse' rack (2.2.3) lib/rack/multipart.rb:54:in extract_multipart' rack (2.2.3) lib/rack/request.rb:594:in parse_multipart' rack (2.2.3) lib/rack/request.rb:446:in POST' actionpack (7.0.2.4) lib/action_dispatch/http/request.rb:391:in block (2 levels) in POST' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:90:in block in parse_formatted_parameters' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:90:in fetch' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:90:in parse_formatted_parameters' actionpack (7.0.2.4) lib/action_dispatch/http/request.rb:390:in block in POST' rack (2.2.3) lib/rack/request.rb:69:in fetch' rack (2.2.3) lib/rack/request.rb:69:in fetch_header' actionpack (7.0.2.4) lib/action_dispatch/http/request.rb:389:in POST' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:55:in parameters' actionpack (7.0.2.4) lib/action_dispatch/http/filter_parameters.rb:48:in filtered_parameters' actionpack (7.0.2.4) lib/action_controller/metal/instrumentation.rb:57:in process_action' actionpack (7.0.2.4) lib/action_controller/metal/params_wrapper.rb:259:in process_action' activerecord (7.0.2.4) lib/active_record/railties/controller_runtime.rb:27:in process_action' actionpack (7.0.2.4) lib/abstract_controller/base.rb:151:in process' actionview (7.0.2.4) lib/action_view/rendering.rb:39:in process' actionpack (7.0.2.4) lib/action_controller/metal.rb:188:in dispatch' actionpack (7.0.2.4) lib/action_controller/metal.rb:251:in dispatch' actionpack (7.0.2.4) lib/action_dispatch/routing/route_set.rb:49:in dispatch' actionpack (7.0.2.4) lib/action_dispatch/routing/route_set.rb:32:in serve' actionpack (7.0.2.4) lib/action_dispatch/journey/router.rb:50:in block in serve' actionpack (7.0.2.4) lib/action_dispatch/journey/router.rb:32:in each' actionpack (7.0.2.4) lib/action_dispatch/journey/router.rb:32:in serve' actionpack (7.0.2.4) lib/action_dispatch/routing/route_set.rb:850:in call' warden (1.2.9) lib/warden/manager.rb:36:in block in call' warden (1.2.9) lib/warden/manager.rb:34:in catch' warden (1.2.9) lib/warden/manager.rb:34:in call' rack (2.2.3) lib/rack/tempfile_reaper.rb:15:in call' rack (2.2.3) lib/rack/etag.rb:27:in call' rack (2.2.3) lib/rack/conditional_get.rb:40:in call' rack (2.2.3) lib/rack/head.rb:12:in call' actionpack (7.0.2.4) lib/action_dispatch/http/permissions_policy.rb:22:in call' actionpack (7.0.2.4) lib/action_dispatch/http/content_security_policy.rb:18:in call' rack (2.2.3) lib/rack/session/abstract/id.rb:266:in context' rack (2.2.3) lib/rack/session/abstract/id.rb:260:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/cookies.rb:693:in call' activerecord (7.0.2.4) lib/active_record/migration.rb:603:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/callbacks.rb:27:in block in call' activesupport (7.0.2.4) lib/active_support/callbacks.rb:99:in run_callbacks' actionpack (7.0.2.4) lib/action_dispatch/middleware/callbacks.rb:26:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/debug_exceptions.rb:28:in call' web-console (4.2.0) lib/web_console/middleware.rb:132:in call_app' web-console (4.2.0) lib/web_console/middleware.rb:28:in block in call' web-console (4.2.0) lib/web_console/middleware.rb:17:in catch' web-console (4.2.0) lib/web_console/middleware.rb:17:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/show_exceptions.rb:26:in call' railties (7.0.2.4) lib/rails/rack/logger.rb:36:in call_app' railties (7.0.2.4) lib/rails/rack/logger.rb:25:in block in call' activesupport (7.0.2.4) lib/active_support/tagged_logging.rb:99:in block in tagged' activesupport (7.0.2.4) lib/active_support/tagged_logging.rb:37:in tagged' activesupport (7.0.2.4) lib/active_support/tagged_logging.rb:99:in tagged' railties (7.0.2.4) lib/rails/rack/logger.rb:25:in call' sprockets-rails (7137bb169839) lib/sprockets/rails/quiet_assets.rb:13:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/remote_ip.rb:93:in call' request_store (1.5.1) lib/request_store/middleware.rb:19:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/request_id.rb:26:in call' rack (2.2.3) lib/rack/method_override.rb:24:in call' rack (2.2.3) lib/rack/runtime.rb:22:in call' activesupport (7.0.2.4) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/static.rb:23:in call' rack (2.2.3) lib/rack/sendfile.rb:110:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/host_authorization.rb:131:in call' prometheus_exporter (2.0.2) lib/prometheus_exporter/middleware.rb:34:in call' webpacker (5.4.3) lib/webpacker/dev_server_proxy.rb:25:in perform_request' rack-proxy (0.7.2) lib/rack/proxy.rb:67:in call' railties (7.0.2.4) lib/rails/engine.rb:530:in call' puma (4.3.12) lib/puma/configuration.rb:228:in call' puma (4.3.12) lib/puma/server.rb:727:in handle_request' puma (4.3.12) lib/puma/server.rb:476:in process_client' puma (4.3.12) lib/puma/server.rb:332:in block in run' puma (4.3.12) lib/puma/thread_pool.rb:134:in block in spawn_thread'

Full Trace rack (2.2.3) lib/rack/query_parser.rb:104:in normalize_params' rack (2.2.3) lib/rack/query_parser.rb:118:in normalize_params' rack (2.2.3) lib/rack/multipart/parser.rb:195:in block (2 levels) in result' rack (2.2.3) lib/rack/multipart/parser.rb:104:in get_data' rack (2.2.3) lib/rack/multipart/parser.rb:193:in block in result' rack (2.2.3) lib/rack/multipart/parser.rb:127:in block in each' rack (2.2.3) lib/rack/multipart/parser.rb:127:in each' rack (2.2.3) lib/rack/multipart/parser.rb:127:in each' rack (2.2.3) lib/rack/multipart/parser.rb:192:in result' rack (2.2.3) lib/rack/multipart/parser.rb:81:in parse' rack (2.2.3) lib/rack/multipart.rb:54:in extract_multipart' rack (2.2.3) lib/rack/request.rb:594:in parse_multipart' rack (2.2.3) lib/rack/request.rb:446:in POST' actionpack (7.0.2.4) lib/action_dispatch/http/request.rb:391:in block (2 levels) in POST' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:90:in block in parse_formatted_parameters' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:90:in fetch' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:90:in parse_formatted_parameters' actionpack (7.0.2.4) lib/action_dispatch/http/request.rb:390:in block in POST' rack (2.2.3) lib/rack/request.rb:69:in fetch' rack (2.2.3) lib/rack/request.rb:69:in fetch_header' actionpack (7.0.2.4) lib/action_dispatch/http/request.rb:389:in POST' actionpack (7.0.2.4) lib/action_dispatch/http/parameters.rb:55:in parameters' actionpack (7.0.2.4) lib/action_dispatch/http/filter_parameters.rb:48:in filtered_parameters' actionpack (7.0.2.4) lib/action_controller/metal/instrumentation.rb:57:in process_action' actionpack (7.0.2.4) lib/action_controller/metal/params_wrapper.rb:259:in process_action' activerecord (7.0.2.4) lib/active_record/railties/controller_runtime.rb:27:in process_action' actionpack (7.0.2.4) lib/abstract_controller/base.rb:151:in process' actionview (7.0.2.4) lib/action_view/rendering.rb:39:in process' actionpack (7.0.2.4) lib/action_controller/metal.rb:188:in dispatch' actionpack (7.0.2.4) lib/action_controller/metal.rb:251:in dispatch' actionpack (7.0.2.4) lib/action_dispatch/routing/route_set.rb:49:in dispatch' actionpack (7.0.2.4) lib/action_dispatch/routing/route_set.rb:32:in serve' actionpack (7.0.2.4) lib/action_dispatch/journey/router.rb:50:in block in serve' actionpack (7.0.2.4) lib/action_dispatch/journey/router.rb:32:in each' actionpack (7.0.2.4) lib/action_dispatch/journey/router.rb:32:in serve' actionpack (7.0.2.4) lib/action_dispatch/routing/route_set.rb:850:in call' warden (1.2.9) lib/warden/manager.rb:36:in block in call' warden (1.2.9) lib/warden/manager.rb:34:in catch' warden (1.2.9) lib/warden/manager.rb:34:in call' rack (2.2.3) lib/rack/tempfile_reaper.rb:15:in call' rack (2.2.3) lib/rack/etag.rb:27:in call' rack (2.2.3) lib/rack/conditional_get.rb:40:in call' rack (2.2.3) lib/rack/head.rb:12:in call' actionpack (7.0.2.4) lib/action_dispatch/http/permissions_policy.rb:22:in call' actionpack (7.0.2.4) lib/action_dispatch/http/content_security_policy.rb:18:in call' rack (2.2.3) lib/rack/session/abstract/id.rb:266:in context' rack (2.2.3) lib/rack/session/abstract/id.rb:260:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/cookies.rb:693:in call' activerecord (7.0.2.4) lib/active_record/migration.rb:603:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/callbacks.rb:27:in block in call' activesupport (7.0.2.4) lib/active_support/callbacks.rb:99:in run_callbacks' actionpack (7.0.2.4) lib/action_dispatch/middleware/callbacks.rb:26:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/debug_exceptions.rb:28:in call' web-console (4.2.0) lib/web_console/middleware.rb:132:in call_app' web-console (4.2.0) lib/web_console/middleware.rb:28:in block in call' web-console (4.2.0) lib/web_console/middleware.rb:17:in catch' web-console (4.2.0) lib/web_console/middleware.rb:17:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/show_exceptions.rb:26:in call' railties (7.0.2.4) lib/rails/rack/logger.rb:36:in call_app' railties (7.0.2.4) lib/rails/rack/logger.rb:25:in block in call' activesupport (7.0.2.4) lib/active_support/tagged_logging.rb:99:in block in tagged' activesupport (7.0.2.4) lib/active_support/tagged_logging.rb:37:in tagged' activesupport (7.0.2.4) lib/active_support/tagged_logging.rb:99:in tagged' railties (7.0.2.4) lib/rails/rack/logger.rb:25:in call' sprockets-rails (7137bb169839) lib/sprockets/rails/quiet_assets.rb:13:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/remote_ip.rb:93:in call' request_store (1.5.1) lib/request_store/middleware.rb:19:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/request_id.rb:26:in call' rack (2.2.3) lib/rack/method_override.rb:24:in call' rack (2.2.3) lib/rack/runtime.rb:22:in call' activesupport (7.0.2.4) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/static.rb:23:in call' rack (2.2.3) lib/rack/sendfile.rb:110:in call' actionpack (7.0.2.4) lib/action_dispatch/middleware/host_authorization.rb:131:in call' prometheus_exporter (2.0.2) lib/prometheus_exporter/middleware.rb:34:in call' webpacker (5.4.3) lib/webpacker/dev_server_proxy.rb:25:in perform_request' rack-proxy (0.7.2) lib/rack/proxy.rb:67:in call' railties (7.0.2.4) lib/rails/engine.rb:530:in call' puma (4.3.12) lib/puma/configuration.rb:228:in call' puma (4.3.12) lib/puma/server.rb:727:in handle_request' puma (4.3.12) lib/puma/server.rb:476:in process_client' puma (4.3.12) lib/puma/server.rb:332:in block in run' puma (4.3.12) lib/puma/thread_pool.rb:134:in block in spawn_thread'

Request parameters None

Session dump _csrf_token: "az0j6WdcULwly1XMUlOF-Bz3R2g1gRWb01nYLW4njyI" session_id: "8e5e5fca8599eaca9e7de41f2096fa39" user_return_to: "/" warden.user.user.key: [[5], "$2a$11$8xWSW0PTFhR2j18uAuXIw."]

Env dump GATEWAY_INTERFACE: "CGI/1.2" HTTP_ACCEPT: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, /; q=0.01" HTTP_ACCEPT_ENCODING: "gzip, deflate, br" HTTP_ACCEPT_LANGUAGE: "de-DE,de;q=0.9" HTTP_ORIGIN: "http://127.0.0.1:3000" HTTP_VERSION: "HTTP/1.1" HTTP_X_CSRF_TOKEN: "mhmv50gFefhN-pOC8i9vUIb8T3h5ChcK5Hzw7WqM7LBRBM_9JHywaTlw77rY1w2FyO3QSfopANzPR5Mcx6zHhA" HTTP_X_FORWARDED_FOR: "172.18.0.1" ORIGINAL_SCRIPT_NAME: "" REMOTE_ADDR: "172.18.0.6" SERVER_NAME: "127.0.0.1" SERVER_PROTOCOL: "HTTP/1.1"

Response headers None

zebleck avatar Jun 01 '22 15:06 zebleck

@zebleck

This change has been added here https://github.com/rails/rails/pull/43511 to support submitting an empty collection of files. If your app does not want this support. Then, you can skip it by using these options:

  • Pass include_hidden: false option with file_field. OR
  • Disable this option globally by setting multiple_file_field_include_hidden config to false in initializer: config.active_storage.multiple_file_field_include_hidden = false.

sushantmittal avatar Jun 23 '22 11:06 sushantmittal

This issue has been automatically marked as stale because it has not been commented on for at least three months. The resources of the Rails team are limited, and so we are asking for your help. If you can still reproduce this error on the 7-0-stable branch or on main, please reply with all of the information you have about it in order to keep the issue open. Thank you for all your contributions.

rails-bot[bot] avatar Sep 21 '22 12:09 rails-bot[bot]