docusealco/docuseal · error · Submitters::SubmitValues::ValidationError
Invalid field
Error message
Invalid field
What it means
Raised by Submitters::SubmitValues.maybe_set_signature_reason! when a submit request carries a with_reason parameter (declining a signature with a reason) and the template field found under that reason UUID already exists, but its preferences.signature_field_uuid does not point at the signature field whose UUID is the other key in the submitted values hash. The service auto-creates and links a reason field only when the reason UUID is brand new; an existing field must already belong to that exact signature field.
Source
Thrown at lib/submitters/submit_values.rb:122
end
def maybe_set_signature_reason!(values, submitter, params)
return if params[:with_reason].blank?
reason_field_uuid = params[:with_reason]
signature_field_uuid = values.except(reason_field_uuid).keys.first
signature_field = submitter.submission.template_fields.find do |e|
e['uuid'] == signature_field_uuid && e['submitter_uuid'] == submitter.uuid
end
reason_field = submitter.submission.template_fields.find do |e|
e['uuid'] == reason_field_uuid
end
if reason_field
if reason_field.dig('preferences', 'signature_field_uuid') != signature_field['uuid']
raise ValidationError, 'Invalid field'
end
else
reason_field = { 'type' => 'text',
'uuid' => reason_field_uuid,
'name' => I18n.t(:reason),
'readonly' => true,
'preferences' => { 'signature_field_uuid' => signature_field['uuid'] },
'submitter_uuid' => submitter.uuid }
submitter.submission.template_fields.insert(submitter.submission.template_fields.index(signature_field) + 1,
reason_field)
end
signature_field['preferences'] ||= {}
signature_field['preferences']['reason_field_uuid'] = reason_field_uuid
submitter.submission.save!
View on GitHub (pinned to 004a22c1c8)
Solutions
- Send a freshly generated UUID as with_reason for each declined signature so the service creates and links the reason field itself
- If reusing an existing reason field, verify field['preferences']['signature_field_uuid'] equals the signature field UUID you are submitting before sending
- Fix the template so the reason field's preferences.signature_field_uuid references the intended signature field
- Omit with_reason entirely if no decline reason needs to be recorded
Example fix
# before
Submitters::SubmitValues.call(submitter, { values: { 'sig_a_uuid' => 'Declined' }, with_reason: 'reason_uuid_created_for_sig_b' }, request)
# after — fresh uuid lets the service create + link the reason field to sig_a
Submitters::SubmitValues.call(submitter, { values: { 'sig_a_uuid' => 'Declined' }, with_reason: SecureRandom.uuid }, request) Defensive patterns
Strategy: validation
Validate before calling
sig_uuid = values.except(params[:with_reason]).keys.first
existing = submitter.submission.template_fields.find { |f| f['uuid'] == params[:with_reason] }
if existing && existing.dig('preferences', 'signature_field_uuid') != sig_uuid
params[:with_reason] = SecureRandom.uuid # let the service create a fresh linked reason field
end Try / catch
begin
Submitters::SubmitValues.update_submitter!(submitter, params, request)
rescue Submitters::SubmitValues::ValidationError => e
# e.message == 'Invalid field': with_reason uuid is linked to another signature field
render json: { error: e.message }, status: :unprocessable_entity
end Prevention
- Generate a new reason UUID per declined signature; never share one across signature fields
- When re-sending a decline, reuse the reason UUID only for the same signature field
- Treat preferences.signature_field_uuid as the link key: reason field and signature must match 1:1
When it happens
Trigger: Submitting values containing exactly one signature-field UUID plus params[:with_reason] = '<uuid>', where '<uuid>' matches an existing template_fields entry (a reason field created for a different signature, or any unrelated field) whose preferences.signature_field_uuid differs from the signature field UUID being submitted.
Common situations: A front-end reuses one hard-coded reason UUID for several signature fields; a template was copied so a reason field linked to another signature survives; a client passes an existing field's UUID instead of generating a fresh one; retrying a decline against a different signature field with the same reason UUID.
Related errors
- Missing field
- Read-only field
- ID Not Verified
- Formula infinite loop
- Templates::ModifyDocuments::InvalidLayout
AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21).
Data as JSON: /api/errors/51cea1c6011aa408.
Report an issue: GitHub.