{"record":{"id":"d79c93a6673331da","repo":"chinabugotech/hutool","slug":"invalid-number-number","errorCode":null,"errorMessage":"invalid number: {number}","messagePattern":"invalid number: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/codec/Hashids.java","lineNumber":208,"sourceCode":"\t * @param numbers 数字数组\n\t * @return 编码后的值, {@code null} if {@code numbers} 是 {@code null}.\n\t * @throws IllegalArgumentException 数字不支持抛出此异常\n\t */\n\t@Override\n\tpublic String encode(final long... numbers) {\n\t\tif (numbers == null) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// copy alphabet\n\t\tfinal char[] currentAlphabet = Arrays.copyOf(alphabet, alphabet.length);\n\n\t\t// determine the lottery number\n\t\tfinal long lotteryId = LongStream.range(0, numbers.length)\n\t\t\t\t.reduce(0, (state, i) -> {\n\t\t\t\t\tfinal long number = numbers[(int) i];\n\t\t\t\t\tif (number < 0) {\n\t\t\t\t\t\tthrow new IllegalArgumentException(\"invalid number: \" + number);\n\t\t\t\t\t}\n\t\t\t\t\treturn state + number % (i + LOTTERY_MOD);\n\t\t\t\t});\n\t\tfinal char lottery = currentAlphabet[(int) (lotteryId % currentAlphabet.length)];\n\n\t\t// encode each number\n\t\tfinal StringBuilder global = new StringBuilder();\n\t\tIntStream.range(0, numbers.length)\n\t\t\t\t.forEach(idx -> {\n\t\t\t\t\t// derive alphabet\n\t\t\t\t\tderiveNewAlphabet(currentAlphabet, salt, lottery);\n\n\t\t\t\t\t// encode\n\t\t\t\t\tfinal int initialLength = global.length();\n\t\t\t\t\ttranslate(numbers[idx], currentAlphabet, global, initialLength);\n\n\t\t\t\t\t// prepend the lottery\n\t\t\t\t\tif (idx == 0) {","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/codec/Hashids.java#L190-L226","documentation":"Hashids encodes an array of non-negative integers; the algorithm (lottery selection and per-number encoding) assumes numbers >= 0. If any element is negative the encode stream throws IllegalArgumentException naming the bad number. This is the standard Hashids contract — it cannot represent negative values.","triggerScenarios":"hashids.encode(...numbers) where at least one number is negative; passing a List/array of Long containing negative ids.","commonSituations":"Encoding database ids that can be negative in test fixtures; subtracting without clamping; overflow wrapping to negative.","solutions":["Filter or clamp values to >= 0 before encoding (e.g. Math.max(0, n)).","Document that Hashids only supports non-negative integers; choose a different scheme if negatives are required.","Validate the input array with Arrays.stream(...).allMatch(n -> n >= 0) before calling encode."],"exampleFix":"// before\nString h = hashids.encode(-1, 42);\n// after\nlong[] safe = Arrays.stream(nums).map(n -> Math.max(0, n)).toArray();\nString h = hashids.encode(safe);","handlingStrategy":"validation","validationCode":"if (Arrays.stream(numbers).anyMatch(n -> n < 0)) throw new IllegalArgumentException(\"Hashids requires non-negative numbers\");","typeGuard":"static boolean allNonNeg(long[] ns) { return ns != null && Arrays.stream(ns).allMatch(n -> n >= 0); }","tryCatchPattern":"try { return hashids.encode(nums); } catch (IllegalArgumentException e) { return hashids.encode(Arrays.stream(nums).map(n->Math.max(0,n)).toArray()); }","preventionTips":["Clamp or filter ids to >= 0 before encoding.","Pick a different encoding if negatives are required."],"tags":["hashids","codec","argument-validation"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}