{"record":{"id":"51cea1c6011aa408","repo":"docusealco/docuseal","slug":"invalid-field","errorCode":null,"errorMessage":"Invalid field","messagePattern":"Invalid field","errorType":"validation","errorClass":"Submitters::SubmitValues::ValidationError","httpStatus":422,"severity":"error","filePath":"lib/submitters/submit_values.rb","lineNumber":122,"sourceCode":"    end\n\n    def maybe_set_signature_reason!(values, submitter, params)\n      return if params[:with_reason].blank?\n\n      reason_field_uuid = params[:with_reason]\n      signature_field_uuid = values.except(reason_field_uuid).keys.first\n\n      signature_field = submitter.submission.template_fields.find do |e|\n        e['uuid'] == signature_field_uuid && e['submitter_uuid'] == submitter.uuid\n      end\n\n      reason_field = submitter.submission.template_fields.find do |e|\n        e['uuid'] == reason_field_uuid\n      end\n\n      if reason_field\n        if reason_field.dig('preferences', 'signature_field_uuid') != signature_field['uuid']\n          raise ValidationError, 'Invalid field'\n        end\n      else\n        reason_field = { 'type' => 'text',\n                         'uuid' => reason_field_uuid,\n                         'name' => I18n.t(:reason),\n                         'readonly' => true,\n                         'preferences' => { 'signature_field_uuid' => signature_field['uuid'] },\n                         'submitter_uuid' => submitter.uuid }\n\n        submitter.submission.template_fields.insert(submitter.submission.template_fields.index(signature_field) + 1,\n                                                    reason_field)\n      end\n\n      signature_field['preferences'] ||= {}\n      signature_field['preferences']['reason_field_uuid'] = reason_field_uuid\n\n      submitter.submission.save!\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/lib/submitters/submit_values.rb#L104-L140","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nSubmitters::SubmitValues.call(submitter, { values: { 'sig_a_uuid' => 'Declined' }, with_reason: 'reason_uuid_created_for_sig_b' }, request)\n# after — fresh uuid lets the service create + link the reason field to sig_a\nSubmitters::SubmitValues.call(submitter, { values: { 'sig_a_uuid' => 'Declined' }, with_reason: SecureRandom.uuid }, request)","handlingStrategy":"validation","validationCode":"sig_uuid = values.except(params[:with_reason]).keys.first\nexisting = submitter.submission.template_fields.find { |f| f['uuid'] == params[:with_reason] }\nif existing && existing.dig('preferences', 'signature_field_uuid') != sig_uuid\n  params[:with_reason] = SecureRandom.uuid # let the service create a fresh linked reason field\nend","typeGuard":null,"tryCatchPattern":"begin\n  Submitters::SubmitValues.update_submitter!(submitter, params, request)\nrescue Submitters::SubmitValues::ValidationError => e\n  # e.message == 'Invalid field': with_reason uuid is linked to another signature field\n  render json: { error: e.message }, status: :unprocessable_entity\nend","preventionTips":["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"],"tags":["ruby","rails","e-signature","form-validation","signature-decline"],"backgroundTag":"invalid-field-reference","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}