docusealco/docuseal · error · Submitters::NormalizeValues::InvalidDefaultValue

Invalid value, url, base64 or text < 60 chars is expected: #

Error message

Invalid value, url, base64 or text < 60 chars is expected: #{value.first(200)}...

What it means

Submitters::NormalizeValues#find_or_build_attachment (lib/submitters/normalize_values.rb:222) raises InvalidDefaultValue listing the expected formats when the value matches none of them: not an http(s) URL, not a short typed string for signature/initials (< 60 chars), not base64 that decodes to a recognized non-'octet-stream' MIME type, and not HTML. The message echoes the first 200 chars of the offending value for diagnosis.

Source

Thrown at lib/submitters/normalize_values.rb:222

      raise InvalidDefaultValue, "Invalid #{type} value" if purpose == :bulk

      blob =
        if value.match?(%r{\Ahttps?://})
          raise InvalidDefaultValue, "Invalid #{type} value" unless purpose == :api

          find_or_create_blob_from_url(account, value)
        elsif type.in?(%w[signature initials]) && value.length < 60
          find_or_create_blob_from_text(account, value, type)
        elsif (data = Base64.decode64(value.sub(BASE64_PREFIX_REGEXP, ''))) &&
              (mime_type = Marcel::MimeType.for(data)).exclude?('octet-stream')
          find_or_create_blob_from_base64(account, data, type, mime_type:)
        elsif type == 'image' && (value.starts_with?('<html>') || value.starts_with?('<!DOCTYPE'))
          raise InvalidDefaultValue, "Invalid #{type} value" unless purpose == :api

          find_or_create_blob_from_html(account, value, field)
        else
          raise InvalidDefaultValue, "Invalid value, url, base64 or text < 60 chars is expected: #{value.first(200)}..."
        end

      attachment = for_submitter.attachments.find_by(blob_id: blob.id) if for_submitter

      attachment ||= ActiveStorage::Attachment.new(
        blob:,
        name: 'attachments'
      )

      attachment
    end

    def find_or_create_blob_from_html(_account, value, _field)
      raise InvalidDefaultValue, "HTML content is not allowed: #{value.first(200)}..."
    end

    def find_or_create_blob_from_base64(account, data, type, mime_type: nil)
      checksum = Digest::MD5.base64digest(data)

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. For images/signatures send a proper data URI: 'data:image/png;base64,<clean single-line base64>'.
  2. For signature/initials typed text, keep it under 60 characters so it renders with the font-image generator.
  3. Verify locally that Base64.strict_decode64 succeeds and the bytes' MIME is a concrete type (image/png, image/jpeg, application/pdf) before submitting.
  4. Strip whitespace/newlines from base64 before sending.

Example fix

# before
{ 'default_value' => blob_object.to_s } # '[object Blob]' — matches no branch

# after
{ 'default_value' => "data:image/png;base64,#{base64_single_line}" }
Defensive patterns

Strategy: validation

Validate before calling

# Verify the value matches one accepted branch before submitting
require 'base64'
require 'marcel'

def acceptable_attachment_value?(value, type)
  return true if value.match?(%r{\Ahttps?://}) # API purpose only
  return true if type.in?(%w[signature initials]) && value.length < 60

  data = Base64.decode64(value.sub(%r{\Adata:[^;]+;base64,}, ''))
  data.present? && !Marcel::MimeType.for(data).include?('octet-stream')
rescue ArgumentError
  false
end

Try / catch

begin
  Submitters::NormalizeValues.normalize_attachment_value(value, field, account, attachments, purpose:)
rescue Submitters::NormalizeValues::InvalidDefaultValue => e
  render json: { error: e.message }, status: :unprocessable_entity # message echoes first 200 chars
end

Prevention

When it happens

Trigger: Base64 that decodes to bytes Marcel::MimeType.for reports as application/octet-stream (generic binary, wrong padding, corrupted data URI); a >60-char signature value that is not valid base64; a data URI with an unparsable prefix; stray whitespace/newlines breaking decode64; text sent for a non-signature field where typed text is not accepted.

Common situations: Frontends sending ArrayBuffer or blob references instead of base64; copy-pasting base64 with line wraps; uploads of arbitrary binary (docx renamed, encrypted blobs) as image values; missing 'data:...;base64,' prefix handling (BASE64_PREFIX_REGEXP strips it only when present).

Related errors


AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21). Data as JSON: /api/errors/a0d7c1b5e607d5dd. Report an issue: GitHub.