docusealco/docuseal · error · Submitters::SubmitValues::ValidationError
Read-only field
Error message
Read-only field
What it means
Raised by Submitters::SubmitValues.validate_value! when the values hash writes to a field whose readonly attribute is exactly true. Readonly fields (e.g. the auto-created decline-reason text field, prefilled/computed fields) are display-only; the attempted write is also logged to Rollbar as 'Readonly field' when Rollbar is defined.
Source
Thrown at lib/submitters/submit_values.rb:507
SubmissionEvents.create_with_tracking_data(submitter, 'invite_party', request, { uuid: submitter.uuid })
is_invited = true
end
submission.update!(submitters_order: :preserved) if is_invited
submitter
end
def validate_value!(_value, field, _params, submitter, _request)
raise ValidationError, 'Missing field' unless field
raise ValidationError, 'Invalid field' if field['submitter_uuid'] != submitter.uuid
if field['readonly'] == true
Rollbar.warning("Readonly field #{submitter.id}: #{field['uuid']}") if defined?(Rollbar)
raise ValidationError, 'Read-only field'
end
true
end
end
end
View on GitHub (pinned to 004a22c1c8)
Solutions
- Remove readonly fields from the values payload (slice to writable fields before submitting)
- If the field must be editable, set readonly to false in the template field definition
- Never write values for internally created fields such as decline-reason fields — they are readonly by design
Example fix
# before
values = values.merge('readonly_field_uuid' => 'new value') # raises 'Read-only field'
# after
writable = submitter.submission.template_fields.reject { |f| f['readonly'] == true }
values = values.slice(*writable.map { |f| f['uuid'] }) Defensive patterns
Strategy: validation
Validate before calling
writable_uuids = submitter.submission.template_fields
.reject { |f| f['readonly'] == true }
.map { |f| f['uuid'] }
values = values.slice(*writable_uuids) Type guard
def writable_field?(uuid, submission) field = submission.fields_uuid_index[uuid] !field.nil? && field['readonly'] != true end
Try / catch
begin
Submitters::SubmitValues.call(submitter, params, request)
rescue Submitters::SubmitValues::ValidationError => e
# e.message == 'Read-only field' -> client tried to write a locked field
render json: { error: e.message }, status: :unprocessable_entity
end Prevention
- Track which fields are readonly in the form schema and disable those inputs
- When prefilling defaults server-side, keep a separate readonly set and never echo it back in submit payloads
- Alert on the Rollbar 'Readonly field' warning — it indicates a client sending locked fields
When it happens
Trigger: Submitting a value for a field configured readonly: true in the template — commonly the auto-created 'Reason' field (created with 'readonly' => true) or any field an admin locked after prefilling defaults.
Common situations: An integration prefills readonly defaults and then posts the whole values object back; the auto-created reason field from a previous decline keeps being included in later submits; a UI bug leaves an input enabled for a locked field; template switched a field to readonly but the client still sends it.
Related errors
- Invalid field
- Missing 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/f8364cb88e524462.
Report an issue: GitHub.