we-promise/sure · error · Import::Preflight::PreflightError

content_too_large

content_too_large

Error message

Content is too large. Maximum size is #{Import.max_csv_size / 1.megabyte}MB.

What it means

Import::Preflight#csv_raw_content_attributes (app/models/import/preflight.rb:200) returns HTTP 422 {error: 'content_too_large'} when the raw_file_content string (the in-body alternative to a multipart file) exceeds Import.max_csv_size, the constant 10MB Import::MAX_CSV_SIZE. The check uses content.bytesize, so it measures bytes, not characters. The same guard runs at import creation (app/controllers/api/v1/imports_controller.rb:96).

Source

Thrown at app/models/import/preflight.rb:395

        payload: {
          error: "content_too_large",
          message: "Content is too large. Maximum size is #{SureImport.max_ndjson_size / 1.megabyte}MB."
        }
      )
    end

    def invalid_sure_file_type_response
      Response.new(
        status: :unprocessable_entity,
        payload: {
          error: "invalid_file_type",
          message: "Invalid file type. Please upload a Sure NDJSON file."
        }
      )
    end

    def raise_response(response)
      raise PreflightError, response
    end

    def unsupported_import_type_response
      Response.new(
        status: :unprocessable_entity,
        payload: {
          error: "unsupported_import_type",
          message: "Preflight supports CSV import types and SureImport."
        }
      )
    end
end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Split the content and send multiple imports, each under 10MB
  2. Send a multipart file instead — same cap, but avoids JSON string overhead
  3. Convert to SureImport NDJSON and tune SURE_IMPORT_MAX_NDJSON_SIZE_MB on self-hosted installs
  4. Self-hosted only: change Import::MAX_CSV_SIZE in app/models/import.rb and redeploy

Example fix

# Ruby client, before (one giant payload)
body = { raw_file_content: years_of_csv } # → 422 content_too_large

# after
years_of_csv.bytesize
text = years_of_csv
parts = []
while text.bytesize > 10 * 1024 * 1024
  cut = text.byteslice(0, 9 * 1024 * 1024).rindex("\n") || 9 * 1024 * 1024
  parts << text.byteslice(0, cut)
  text = text.byteslice((cut + 1)..-1).to_s
end
parts << text
parts.each { |p| post_import(raw_file_content: p) }
Defensive patterns

Strategy: validation

Validate before calling

MAX_CSV_BYTES = 10 * 1024 * 1024
raise 'raw_file_content exceeds 10MB' if raw_content.bytesize > MAX_CSV_BYTES
# split on a newline boundary and send several imports

Prevention

When it happens

Trigger: POSTing params[:raw_file_content] whose bytesize exceeds 10485760 bytes — e.g. an in-memory CSV built by concatenating several exports into one JSON body.

Common situations: Building raw_file_content by concatenating monthly exports; base64-encoding the CSV (adds ~33% and pushes over the cap); multi-byte UTF-8 content whose character count looks under the limit while bytesize is over it.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/ba26e7955b4e788e. Report an issue: GitHub.