{"record":{"id":"c2d2fd0533c566e4","repo":"docusealco/docuseal","slug":"recipient-emails-should-differ","errorCode":null,"errorMessage":"Recipient emails should differ","messagePattern":"Recipient emails should differ","errorType":"validation","errorClass":"Submissions::CreateFromSubmitters::BaseError","httpStatus":422,"severity":"error","filePath":"lib/submissions/create_from_submitters.rb","lineNumber":86,"sourceCode":"          is_order_sent = submitters_order == 'random' ||\n                          (template_submitter['order'] || submitter_attrs[:index] || index).zero?\n\n          build_submitter(submission:, attrs: submitter_attrs,\n                          uuid:, is_order_sent:, user:, params:,\n                          preferences: preferences.merge(submission_preferences))\n        end\n\n        maybe_set_dynamic_documents(submission)\n        maybe_set_template_fields(submission, attrs[:submitters], with_template:, new_fields:)\n\n        if submission.submitters.size > template.submitters.size\n          raise BaseError, 'Defined more signing parties than in template'\n        end\n\n        if template.preferences['validate_unique_submitters'] == true\n          submission_emails = submission.submitters.filter_map(&:email)\n\n          raise BaseError, 'Recipient emails should differ' if submission_emails.uniq.size != submission_emails.size\n        end\n\n        next if submission.submitters.blank?\n\n        maybe_add_invite_submitters(submission, template, attrs[:submitters])\n\n        assign_submitters_is_viewer(submission)\n\n        submission.template = nil unless with_template\n\n        submission.tap(&:save!)\n      end\n\n      maybe_enqueue_expire_at(submissions)\n\n      submissions\n    end\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/lib/submissions/create_from_submitters.rb#L68-L104","documentation":"Submissions::CreateFromSubmitters raises BaseError 'Recipient emails should differ' (lib/submissions/create_from_submitters.rb:86) only when the template preference validate_unique_submitters is exactly true. It compares the number of non-nil submitter emails against their uniq size; any duplicated email among the created submitters fails the whole submission create.","triggerScenarios":"POST /api/submissions with two or more submitters entries carrying the same email (case differences count as equal only if normalized the same — Submissions.normalize_email runs first); the same person assigned to two template parties on a template with validate_unique_submitters: true.","commonSituations":"One signer holding multiple roles in a workflow (director + secretary); test payloads reusing one test email for every party; templates where the preference was enabled after integrations went live.","solutions":["Give each party a distinct email address, or merge the person's roles into one submitter entry with roles: ['Role A', 'Role B'] so only one submitter is created.","If the same mailbox must receive both, use an alias (user+role@domain) so the strings differ.","Turn off template.preferences['validate_unique_submitters'] in the template editor if reuse is legitimately allowed by your workflow.","Rescue CreateFromSubmitters::BaseError and return 422 with the message so the client can correct recipients."],"exampleFix":"# before\n{ submitters: [\n  { role: 'Director', email: 'jane@corp.com' },\n  { role: 'Secretary', email: 'jane@corp.com' }\n] }\n\n# after (one party, merged roles)\n{ submitters: [\n  { roles: %w[Director Secretary], email: 'jane@corp.com' }\n] }","handlingStrategy":"validation","validationCode":"# Pre-validate uniqueness when the template enforces it\ndef unique_emails?(template, submitters_attrs)\n  return true unless template.preferences['validate_unique_submitters'] == true\n\n  emails = Array(submitters_attrs).flat_map { |a| Array(a[:submitters]) }.filter_map { |s| s[:email].to_s.downcase.squish }\n  emails.uniq.size == emails.size\nend","typeGuard":null,"tryCatchPattern":"begin\n  Submissions::CreateFromSubmitters.call(template:, user:, submissions_attrs:, source:, submitters_order:)\nrescue Submissions::CreateFromSubmitters::BaseError => e\n  render json: { error: e.message }, status: :unprocessable_entity\nend","preventionTips":["Check template.preferences['validate_unique_submitters'] before reusing one mailbox for several parties.","Prefer merged roles for one person over duplicate emails; or use plus-address aliases.","Normalize emails (downcase) client-side before the uniqueness check so case does not hide dupes.","Surface this as a 422 so the sender can correct recipients."],"tags":["docuseal","submissions","duplicate-email","params-validation"],"backgroundTag":"duplicate-recipient-email","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}