alibaba/COLA · error · IllegalArgumentException

alphabet cannot be null.

Error message

alphabet cannot be null.

What it means

Argument-validation guard inside NanoIdUtils.randomNanoId: the alphabet character array passed to the generator was null, so no character set exists to map random bytes onto. It fires only via the full overload randomNanoId(Random, char[], int) when a caller explicitly supplies a null alphabet; the no-arg convenience method always passes DEFAULT_ALPHABET and cannot trigger it.

Source

Thrown at cola-components/cola-component-job/src/main/java/com/alibaba/cola/job/UuidGenerator.java:66

     * 生成随机的NanoId工具内部类
     */
    public final class NanoIdUtils {
        public static final SecureRandom DEFAULT_NUMBER_GENERATOR = new SecureRandom();
        public static final char[] DEFAULT_ALPHABET = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
        public static final int DEFAULT_SIZE = 21;

        private NanoIdUtils() {
        }

        public static String randomNanoId() {
            return randomNanoId(DEFAULT_NUMBER_GENERATOR, DEFAULT_ALPHABET, 21);
        }

        public static String randomNanoId(Random random, char[] alphabet, int size) {
            if (random == null) {
                throw new IllegalArgumentException("random cannot be null.");
            } else if (alphabet == null) {
                throw new IllegalArgumentException("alphabet cannot be null.");
            } else if (alphabet.length != 0 && alphabet.length < 256) {
                if (size <= 0) {
                    throw new IllegalArgumentException("size must be greater than zero.");
                } else {
                    int mask = (2 << (int)Math.floor(Math.log((double)(alphabet.length - 1)) / Math.log(2.0D))) - 1;
                    int step = (int)Math.ceil(1.6D * (double)mask * (double)size / (double)alphabet.length);
                    StringBuilder idBuilder = new StringBuilder();

                    while(true) {
                        byte[] bytes = new byte[step];
                        random.nextBytes(bytes);

                        for(int i = 0; i < step; ++i) {
                            int alphabetIndex = bytes[i] & mask;
                            if (alphabetIndex < alphabet.length) {
                                idBuilder.append(alphabet[alphabetIndex]);
                                if (idBuilder.length() == size) {
                                    return idBuilder.toString();

View on GitHub (pinned to 352e1a8675)

Solutions

  1. Pass a non-null char[] alphabet, e.g. UuidGenerator.DEFAULT_ALPHABET or "abc...".toCharArray()
  2. Fix the config/provider that returns a null alphabet
  3. Use the no-arg randomNanoId() overload that supplies the default alphabet

Example fix

// before
String id = gen.randomNanoId(random, null, 21);
// after
String id = gen.randomNanoId(random, DEFAULT_ALPHABET, 21);
Defensive patterns

Strategy: validation

Validate before calling

if (alphabet == null || alphabet.length == 0) {
    alphabet = UuidGenerator.DEFAULT_ALPHABET; // or handle explicitly
}

Type guard

char[] safeAlphabet(char[] alphabet) {
    return (alphabet != null && alphabet.length >= 1 && alphabet.length <= 255) ? alphabet : DEFAULT_ALPHABET;
}

Try / catch

try {
    id = UuidGenerator.randomNanoId(random, alphabet, size);
} catch (IllegalArgumentException e) {
    log.warn("alphabet invalid ({}); falling back to default", e.getMessage());
    id = UuidGenerator.randomNanoId();
}

Prevention

When it happens

Trigger: Calling randomNanoId(random, null, size) with a null alphabet array.

Common situations: Loading a custom alphabet from config that failed to initialize; passing a null result of a builder method; typo where DEFAULT_ALPHABET was replaced by null.

Related errors


AI-assisted analysis of alibaba/COLA@352e1a8675 (2026-09-08). Data as JSON: /api/errors/2875a6cb34dec8b2. Report an issue: GitHub.