apache/cassandra · error · InvalidRequestException

Argument ' ' cannot be frozen; remove frozen<> modifier from

Error message

Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'

What it means

CreateAggregateStatement.apply validation: one of the aggregate's argument types is declared frozen<>, which is meaningless/unsupported for function arguments; the frozen modifier must be removed from that argument type.

Solutions

  1. Remove the frozen<> modifier from the argument type in CREATE AGGREGATE
  2. Use the plain collection/UDT type (e.g. list<int> instead of frozen<list<int>>)
  3. Only use frozen<> where the schema genuinely requires it (table columns), not function args

Example fix

// before
CREATE AGGREGATE ks.f(frozen<list<int>>) ...
// after
CREATE AGGREGATE ks.f(list<int>) ...
Defensive patterns

Strategy: validation

Validate before calling

args.forEach(t -> { if (t.contains("frozen<") && !isImplicitlyFrozen(t)) throw new IllegalArgumentException("Remove frozen<> from arg: " + t); });

Try / catch

try { session.execute(ddl); }
catch (InvalidRequestException e) { if (e.getMessage().contains("cannot be frozen")) retryWithUnfrozenArgs(ddl); else throw e; }

Prevention

When it happens

Trigger: Any rawArgumentTypes entry where raw.isFrozen() is true and isImplicitlyFrozen() is false, e.g. frozen<list<int>> written by the user in the aggregate signature.

Common situations: Copy-pasting frozen<> from table column definitions into aggregate signatures; misunderstanding when frozen<> is required.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java:114

    @Override
    public boolean compatibleWith(ClusterMetadata metadata)
    {
        return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);
    }

    @Override
    public Keyspaces apply(ClusterMetadata metadata)
    {
        if (ifNotExists && orReplace)
            throw ire("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives");

        if (!FunctionName.isNameValid(aggregateName))
            throw ire("Aggregate name '%s' is invalid", aggregateName);

        rawArgumentTypes.stream()
                        .filter(raw -> !raw.isImplicitlyFrozen() && raw.isFrozen())
                        .findFirst()
                        .ifPresent(t -> { throw ire("Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'", t, t); });

        if (!rawStateType.isImplicitlyFrozen() && rawStateType.isFrozen())
            throw ire("State type '%s' cannot be frozen; remove frozen<> modifier from '%s'", rawStateType, rawStateType);

        Keyspaces schema = metadata.schema.getKeyspaces();
        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
        if (null == keyspace)
            throw ire("Keyspace '%s' doesn't exist", keyspaceName);

        /*
         * Resolve the state function
         */

        List<AbstractType<?>> argumentTypes =
            rawArgumentTypes.stream()
                            .map(t -> t.prepare(keyspaceName, keyspace.types).getType().udfType())
                            .collect(toList());
        AbstractType<?> stateType = rawStateType.prepare(keyspaceName, keyspace.types).getType().udfType();

View on GitHub (pinned to 88fd0f6a0e)