{"record":{"id":"bc6e32172ea03f25","repo":"TheAlgorithms/Java","slug":"cardnumber-is-not-a-card-number","errorCode":null,"errorMessage":"{\" + cardNumber + \"} - is not a card number","messagePattern":"(.+?) - is not a card number","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/others/Luhn.java","lineNumber":114,"sourceCode":"     */\n    /**\n     * Object representation of credit card.\n     */\n    private record CreditCard(int[] digits) {\n        private static final int DIGITS_COUNT = 16;\n\n        /**\n         * @param cardNumber string representation of credit card number - 16\n         * digits. Can have spaces for digits separation\n         * @return credit card object\n         * @throws IllegalArgumentException if input string is not 16 digits or\n         * if Luhn check was failed\n         */\n        public static CreditCard fromString(String cardNumber) {\n            Objects.requireNonNull(cardNumber);\n            String trimmedCardNumber = cardNumber.replaceAll(\" \", \"\");\n            if (trimmedCardNumber.length() != DIGITS_COUNT || !trimmedCardNumber.matches(\"\\\\d+\")) {\n                throw new IllegalArgumentException(\"{\" + cardNumber + \"} - is not a card number\");\n            }\n\n            int[] cardNumbers = toIntArray(trimmedCardNumber);\n            boolean isValid = luhnCheck(cardNumbers);\n            if (!isValid) {\n                throw new IllegalArgumentException(\"Credit card number {\" + cardNumber + \"} - have a typo\");\n            }\n\n            return new CreditCard(cardNumbers);\n        }\n\n        /**\n         * @return string representation separated by space every 4 digits.\n         * Example: \"5265 9251 6151 1412\"\n         */\n        public String number() {\n            StringBuilder result = new StringBuilder();\n            for (int i = 0; i < DIGITS_COUNT; i++) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/others/Luhn.java#L96-L132","documentation":"Thrown by Luhn.CreditCard.fromString when the input, after removing spaces, is not exactly 16 characters of digits (DIGITS_COUNT = 16). The method requires a 16-digit numeric string before it even attempts the Luhn checksum; failing format yields this 'is not a card number' error.","triggerScenarios":"Calling CreditCard.fromString(s) where s trims to a length other than 16, or contains non-digit characters (letters, dashes, dots). Passing 15-digit or 17-digit numbers; passing numbers with '-' separators that are not stripped (only spaces are stripped).","commonSituations":"User typing a card number with dashes or dots; AMEX (15-digit) or other non-16-digit cards passed to this 16-digit-only API; copy-paste introducing hidden characters; truncation/padding mistakes.","solutions":["Normalize the input: strip all non-digit characters, then verify length == 16 before calling.","If the card may have a different length (e.g. AMEX), do not use this method; route to a length-agnostic validator.","Validate format with a regex (\\\\d{16}) on the cleaned string before invoking fromString.","Tell users to enter 16 digits with optional spaces only."],"exampleFix":"// before\nCreditCard cc = CreditCard.fromString(rawInput); // rawInput may contain dashes / wrong length\n\n// after\nString digits = rawInput.replaceAll(\"\\\\D\", \"\");\nif (digits.length() != 16) {\n    throw new IllegalArgumentException(\"Expected 16 digits, got \" + digits.length());\n}\nCreditCard cc = CreditCard.fromString(digits);","handlingStrategy":"validation","validationCode":"String digits = cardNumber.replaceAll(\"\\\\D\", \"\");\nif (digits.length() != 16 || !digits.matches(\"\\\\d{16}\")) {\n    throw new IllegalArgumentException(\"Expected 16 digits; got: \" + cardNumber);\n}\nCreditCard cc = CreditCard.fromString(digits);","typeGuard":"public static boolean looksLikeCardNumber(String s) {\n    if (s == null) return false;\n    String digits = s.replaceAll(\"\\\\D\", \"\");\n    return digits.length() == 16 && digits.matches(\"\\\\d+\");\n}","tryCatchPattern":"try {\n    cc = CreditCard.fromString(raw);\n} catch (IllegalArgumentException e) {\n    // format problem: ask user to re-enter 16 digits\n    errors.add(\"Card number must be 16 digits.\");\n}","preventionTips":["Strip all non-digit characters and check length == 16 before calling.","This API is 16-digit only; route AMEX/other lengths elsewhere.","Only spaces are tolerated by fromString; dashes/dots are not stripped."],"tags":["validation","luhn","credit-card","input-validation","format"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}