{"record":{"id":"4862ccace4a0e26c","repo":"antiwork/gumroad","slug":"missing-to-sentence-missing-length-1-is","errorCode":null,"errorMessage":"#{missing.to_sentence} #{missing.length == 1 ? \"is\" : \"are\"} required for beneficial owners — Stripe needs them to verify the person.","messagePattern":"#(.+?) #(.+?) required for beneficial owners — Stripe needs them to verify the person\\.","errorType":"exception","errorClass":"StripeBeneficialOwnersManager::MissingRequiredFieldError","httpStatus":422,"severity":"error","filePath":"app/business/payments/merchant_registration/implementations/stripe/stripe_beneficial_owners_manager.rb","lineNumber":163,"sourceCode":"          label if address[key].to_s.strip.empty?\n        end\n      end\n    elsif action == :create\n      missing += is_jp_seller ? REQUIRED_JP_ADDRESS_FIELDS.values : REQUIRED_ADDRESS_FIELDS.values\n    end\n    if action == :create\n      missing += REQUIRED_CREATE_ONLY_FIELDS.filter_map do |key, label|\n        label if params[key].to_s.strip.empty?\n      end\n    end\n    if action == :create && COUNTRIES_REQUIRING_NATIONALITY.include?(seller_country) && params[:nationality].to_s.strip.empty?\n      missing << \"Nationality\"\n    end\n    if truthy?(params[:owner]) && params[:percent_ownership].to_s.strip.empty?\n      missing << \"Ownership percentage\"\n    end\n    return if missing.empty?\n    raise MissingRequiredFieldError, \"#{missing.to_sentence} #{missing.length == 1 ? \"is\" : \"are\"} required for beneficial owners — Stripe needs them to verify the person.\"\n  end\n  private_class_method :validate_required_fields!\n\n  def self.required_address_fields_for(country_code)\n    fields = REQUIRED_ADDRESS_FIELDS\n    fields = fields.except(:postal_code) if COUNTRIES_WITHOUT_POSTAL_CODE.include?(country_code)\n    fields = fields.except(:state) unless COUNTRIES_WITH_STATE_LIST.include?(country_code)\n    fields\n  end\n  private_class_method :required_address_fields_for\n\n  # Server-side counterpart of the kana-format checks the beneficial-owner form runs in the\n  # browser. Without this, a direct API request could put non-katakana text in a kana field\n  # and we would forward it to Stripe as address_kana/first_name_kana, which Stripe rejects\n  # for Japanese accounts. Reuses the same regexes UserComplianceInfo applies to the\n  # seller's own kana fields.\n  def self.validate_jp_kana_address_format!(params, user)\n    validate_kana_param!(params[:first_name_kana], \"First name (Kana)\", UserComplianceInfo::KANA_NAME_REGEX, \"katakana characters, spaces, dashes, and dots\")","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/antiwork/gumroad/blob/afeacbd394069a1cbf0c6c50ee8e900925050370/app/business/payments/merchant_registration/implementations/stripe/stripe_beneficial_owners_manager.rb#L145-L181","documentation":"MissingRequiredFieldError from StripeBeneficialOwnersManager.validate_required_fields! during Stripe merchant (connected-account) onboarding. It aggregates every empty required beneficial-owner field — the base set, plus create-only fields when action == :create, plus Nationality for countries in COUNTRIES_REQUIRING_NATIONALITY, plus Ownership percentage when params[:owner] is truthy — and raises one message listing all of them (\"X, Y and Z are required for beneficial owners…\"). It runs before any Stripe API call so Stripe never receives an incomplete Person.","triggerScenarios":"POSTing/PATCHing beneficial-owner person params via the merchant-registration flow (create or update) with any required key blank: e.g. creating an owner without first/last name, dob, or address lines; creating for a JP/other nationality-required country with params[:nationality] empty; marking owner=true (truthy) without percent_ownership.","commonSituations":"Front-end form skipping fields conditionally (e.g. hiding nationality for non-US/JP and forgetting the create-only set); API integrations not sending percent_ownership when relationship.owner is set; update calls assuming create-only fields aren't needed (they are only checked on :create — blanks on update pass); truthiness traps where params[:owner] is the string \"false\" and still counts as truthy.","solutions":["Fill in every field named in the message — the error already enumerates exactly which labels are missing; resubmit with those keys non-blank.","Check action semantics: on :create the REQUIRED_CREATE_ONLY_FIELDS are also mandatory; on :update only the base set is, so an update failing means a base field is blank.","Send percent_ownership whenever owner is truthy in your payload semantics (and send a real boolean, not the string \"false\", if ownership is not claimed).","For sellers in nationality-requiring countries, make the nationality input required in the UI for create."],"exampleFix":"# before: owner flagged without ownership share\nStripeBeneficialOwnersManager.create_person({ owner: true, first_name: \"A\", last_name: \"B\", dob: \"1990-01-01\" }, user)\n# after: include every required field for create\nStripeBeneficialOwnersManager.create_person({ owner: true, percent_ownership: \"55\", first_name: \"A\", last_name: \"B\", dob: \"1990-01-01\", nationality: \"JP\", address: {...} }, user)","handlingStrategy":"validation","validationCode":"missing = REQUIRED_FIELDS.select { |k, _| params[k].to_s.strip.empty? }.map(&:last)\nmissing += [\"Ownership percentage\"] if truthy_owner_without_percent?(params)\nreturn Result.invalid(missing) unless missing.empty?","typeGuard":"def beneficial_owner_params_complete?(params, action:, seller_country:)\n  keys = StripeBeneficialOwnersManager::REQUIRED_FIELDS.keys\n  keys += StripeBeneficialOwnersManager::REQUIRED_CREATE_ONLY_FIELDS.keys if action == :create\n  keys.all? { |k| params[k].to_s.strip.present? } &&\n    !(truthy?(params[:owner]) && params[:percent_ownership].to_s.strip.empty?)\nend","tryCatchPattern":null,"preventionTips":["Make every required field required in the UI, including create-only fields and nationality per country.","Send percent_ownership whenever the owner flag is truthy — use real booleans, not strings.","Validate the full payload client-side with the same field list to avoid multi-round-trip failures."],"tags":["stripe","onboarding","kyc","beneficial-owners","validation"],"backgroundTag":"missing-required-onboarding-fields","analyzedSha":"afeacbd394069a1cbf0c6c50ee8e900925050370","analyzedAt":"2026-08-21T17:58:52.159Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}