{"record":{"id":"8b93de2761dc0b53","repo":"faker-ruby/faker","slug":"invalid-birthday-birthday-danish-cpr-numbers","errorCode":null,"errorMessage":"Invalid birthday: #{birthday}. Danish CPR numbers are only distributed to persons born between 1858 and 2057.","messagePattern":"Invalid birthday: #(.+?)\\. Danish CPR numbers are only distributed to persons born between 1858 and 2057\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/faker/default/id_number.rb","lineNumber":393,"sourceCode":"        subtraction = 11 - remainder.to_i\n        digits = { 10 => 'X', 11 => '0' }\n        digits.include?(subtraction) ? digits[subtraction] : subtraction.to_s\n      end\n\n      def danish_control_digits(birthday)\n        year = birthday.year\n        century = year.to_s.slice(0, 2).to_i\n        year_digits = year.to_s.slice(2, 2).to_i\n        error_message = \"Invalid birthday: #{birthday}. Danish CPR numbers are only distributed to persons born between 1858 and 2057.\"\n\n        case century\n        when 18\n          # If 5, 6, 7 or 8 and the year numbers are greater than or equal to 58, you were born in 18XX.\n          case year_digits\n          when 58..99\n            [5, 6, 7, 8]\n          else\n            raise ArgumentError, error_message\n          end\n        when 19\n          # If 0, 1, 2 or 3, you are always born in 19XX.\n          # If 4 or 9, you are born in 19XX if the year digits are greater than 36.\n\n          case year_digits\n          when 0..36\n            [0, 1, 2, 3]\n          else # 37..99\n            [0, 1, 2, 3, 4, 9]\n          end\n        else\n          # If 4, 5, 6, 7, 8 or 9 and the year digits are less than or equal to 36, you were born in 20XX.\n          # 5, 6, 7 and 8 are not distributed to persons, with year digits from and including 37 to and including 57.\n          case year_digits\n          when 0..36\n            [4, 5, 6, 7, 8, 9]\n          when 37..57","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/faker-ruby/faker/blob/cca4184947e09fdd02afb8b89d25a9c8ebc7274e/lib/faker/default/id_number.rb#L375-L411","documentation":"Raised by the private danish_control_digits helper in Faker::IdNumber.danish_id_number when the birthday's century is 18xx but the two-digit year is below 58. The Danish CPR sequence-number scheme only encodes birth years from 1858 onward (century digit 5/6/7/8 with year digits >= 58), so a date in 1800-1857 has no valid control digit and the method raises ArgumentError instead of generating an invalid number.","triggerScenarios":"Faker::IdNumber.danish_id_number(birthday: Date.new(1812, 5, 3)) or any birthday between 1800-01-01 and 1857-12-31: century == 18 and year_digits falls outside 58..99, hitting the raise at lib/faker/default/id_number.rb:393.","commonSituations":"Seeding historical test data with very old birthdates; passing Date.parse of free-text user input that contains a mistyped year (e.g. 1050 or 1850 instead of 1950); factories that randomize birthdays over centuries (Faker::Date.birthday defaults to a recent range, so this only occurs with explicit dates).","solutions":["Use a birthday between 1858-01-01 and 2057-12-31, e.g. Date.new(1890, 5, 3).","Clamp or validate user-supplied birthdates before passing them: raise or substitute a default when the year is outside 1858..2057.","If you truly need IDs for pre-1858 persons, CPR cannot represent them; generate a plain numeric identifier instead of a CPR number."],"exampleFix":"# before\nFaker::IdNumber.danish_id_number(birthday: Date.new(1850, 1, 1)) # ArgumentError\n\n# after\nFaker::IdNumber.danish_id_number(birthday: Date.new(1859, 1, 1))","handlingStrategy":"validation","validationCode":"def cpr_compatible_birthday?(date)\n  date.year.between?(1858, 2057)\nend\n\nbirthday = Date.new(1990, 3, 5) if !cpr_compatible_birthday?(user_birthday)\nFaker::IdNumber.danish_id_number(birthday: birthday)","typeGuard":"def cpr_compatible_birthday?(date)\n  date.is_a?(Date) && date.year.between?(1858, 2057)\nend","tryCatchPattern":"begin\n  Faker::IdNumber.danish_id_number(birthday: birthday)\nrescue ArgumentError\n  Faker::IdNumber.danish_id_number(birthday: Faker::Date.birthday) # fall back to default range\nend","preventionTips":["Assert 1858 <= birthday.year <= 2057 before calling danish_id_number.","Validate parsed free-text dates at the boundary (a mistyped year is the usual cause).","Remember the same range applies to the upper bound: 2058+ also raises."],"tags":["faker","argument-error","date-validation","danish-cpr","id-number"],"backgroundTag":"date-out-of-range","analyzedSha":"cca4184947e09fdd02afb8b89d25a9c8ebc7274e","analyzedAt":"2026-08-21T16:25:39.145Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}