Skip to content

Import form submits with no file when direct upload fails #2242

Description

@moveson

Problem

The import form (app/views/import_jobs/_form.html.erb) uses ActiveStorage direct upload via the shared dropzone controller, but its submit button is not gated on upload success. When the browser-to-S3 upload fails, the form still submits, creating an ImportJob with no file attached. The job then fails server-side with:

[{"title":"No records were provided","detail":{"messages":["No records were provided for this import"]}}]

— stored in import_job.error_message, invisible to Scout and opaque to the user, who sees only a failed import job with no hint that the upload itself never happened.

By contrast, the GPX course upload form (app/views/events/_course_gpx_form.html.erb), which uses the same dropzone controller, correctly keeps its Save button disabled until the upload completes — so the same failure surfaces there as a visible client-side error.

Real-world case

2026-08-28: a race timing official setting up Bear 100 on staging hit both forms while the staging S3 bucket's CORS policy still allowed only the defunct Heroku origin (every direct upload failed with Status: 0). The GPX form told him something was wrong with the upload; the CSV form let him queue a job that failed mysteriously, turning a five-minute client-side diagnosis into an email chain and a background-job investigation.

Fix

Gate the import form's submit the same way the GPX form gates Save: disable until the dropzone controller reports the direct upload stored successfully, and keep it disabled (with the error visible) on upload failure. Worth checking whether the difference lives in the form markup or in how each form wires the dropzone controller's targets/actions — the controller evidently supports the correct behavior already.

Belt-and-braces option while in there: Etl::AsyncImporter (or the controller create action) could reject an ImportJob with files.attached? == false up front with a clearer message like "No file was uploaded — the file upload may have failed," rather than the generic "No records were provided."

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    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