apache/cassandra · error · IllegalArgumentException

Value of %s is not a string.

Error message

Value of %s is not a string.

What it means

Thrown by UUIDRoleNameGenerator.enrich() when a value in the options map for a known key (name_prefix, name_suffix, name_size) is present but is not a String. The generator only understands string-typed option values even for name_size.

Source

Thrown at src/java/org/apache/cassandra/db/guardrails/UUIDRoleNameGenerator.java:135

    {
        if (minimumNameSize < DEFAULT_MINIMUM_NAME_SIZE || minimumNameSize > MAXIMUM_NAME_SIZE)
            throw new ConfigurationException(MINIMUM_NAME_SIZE_CONFIG_OPTION + " has to be at least " + DEFAULT_MINIMUM_NAME_SIZE + " and at most " + MAXIMUM_NAME_SIZE);
    }

    private String enrich(String key, String generatedValue, Map<String, Object> options)
    {
        if (options == null || options.isEmpty())
            return generatedValue;

        if (options.containsKey(key))
        {
            Object value = options.get(key);

            if (value == null)
                throw new IllegalArgumentException("Value of " + key + " cannot be null.");

            if (!(value instanceof String))
                throw new IllegalArgumentException("Value of " + key + " is not a string.");

            if (NAME_PREFIX_KEY.equals(key))
                generatedValue = value + generatedValue;
            else if (NAME_SUFFIX_KEY.equals(key))
                generatedValue = generatedValue + value;
        }

        return generatedValue;
    }

    private int getSize(Map<String, Object> options)
    {
        Object sizeObject;
        if (options == null)
        {
            sizeObject = MAXIMUM_NAME_SIZE;
        }
        else if (options.containsKey(NAME_SIZE))

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Convert all option values to String before calling generate, e.g. String.valueOf(value)
  2. For name_size pass the number as a string: "name_size" -> "8"
  3. Check the message for the key name and fix that entry's type

Example fix

// before
options.put("name_prefix", 42);
// after
options.put("name_prefix", "42");
Defensive patterns

Strategy: type-guard

Validate before calling

for (var e : options.entrySet())
    if (e.getValue() != null && !(e.getValue() instanceof String))
        throw new IllegalArgumentException("non-string value for option: " + e.getKey());

Type guard

boolean allStringValues(Map<String,Object> options) {
    return options.values().stream().allMatch(v -> v == null || v instanceof String);
}

Try / catch

try {
    generator.generate(options);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("is not a string")) {
        // coerce offending entry via String.valueOf and retry
    } else throw e;
}

Prevention

When it happens

Trigger: Calling generate(options) with e.g. options.put("name_size", 8) (Integer) or a non-string prefix like options.put("name_prefix", 123), or a config layer deserializing numbers as Integer/Long.

Common situations: Passing parsed YAML/JSON maps where scalars become Integer/Boolean automatically instead of strings; building options in code with native types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/17f34fe46ffbb797. Report an issue: GitHub.