apache/cassandra · error · InvalidRequestException

is not a valid field identifier of type

Error message

%s is not a valid field identifier of type %s 

What it means

When building a UDT selector from a UDT literal in the selection clause, the left side of a `{field: value}` pair is not a plain identifier, so it cannot be resolved to a field of the user type. Only RawIdentifier keys are valid field names. The request is rejected at prepare time.

Solutions

  1. Use a plain (possibly quoted) field name as the key: {street:'x'} instead of an expression key.
  2. Check that the literal is a UDT literal and not intended as a tuple literal (tuples use (v1, v2) syntax).
  3. Validate programmatically generated UDT literal keys are FieldIdentifier-compatible names.

Example fix

// before
SELECT (address) {street(x):'Main'} FROM t;
// after
SELECT (address) {street:'Main'} FROM t;
Defensive patterns

Strategy: validation

Validate before calling

for (String key : literalKeys) if (!key.matches("[a-zA-Z_][a-zA-Z0-9_]*") && !key.startsWith("\"")) throw new IllegalArgumentException("UDT literal key must be a plain identifier: " + key);

Try / catch

try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().contains("not a valid field identifier")) { /* fix the UDT literal key to a plain identifier */ } else throw e; }

Prevention

When it happens

Trigger: `SELECT (udt_type) {f(x):1} FROM t` or a computed/function-call expression used as the field key of a UDT literal; a quoted or nested expression where a simple field identifier is expected.

Common situations: Copy-paste typos in UDT literals; programmatically generated literals where keys are expressions rather than names; confused tuple syntax `{1,2}` vs UDT syntax `{field:val}`.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/selection/Selectable.java:1162

            return MapSelector.newFactory(type, getMapEntries(cfm).stream()
                                                                  .map(p -> Pair.create(p.left.newSelectorFactory(cfm, mapType.getKeysType(), defs, boundNames),
                                                                                        p.right.newSelectorFactory(cfm, mapType.getValuesType(), defs, boundNames)))
                                                                  .collect(Collectors.toList()));
        }

        private Factory newUdtSelectorFactory(TableMetadata cfm,
                                              AbstractType<?> expectedType,
                                              List<ColumnMetadata> defs,
                                              VariableSpecifications boundNames)
        {
            UserType ut = (UserType) expectedType;
            Map<FieldIdentifier, Factory> factories = new LinkedHashMap<>(ut.size());

            for (Pair<Selectable.Raw, Selectable.Raw> raw : raws)
            {
                if (!(raw.left instanceof RawIdentifier))
                    throw invalidRequest("%s is not a valid field identifier of type %s ",
                                         raw.left,
                                         ut.getNameAsString());

                FieldIdentifier fieldName = ((RawIdentifier) raw.left).toFieldIdentifier();
                int fieldPosition = ut.fieldPosition(fieldName);

                if (fieldPosition == -1)
                    throw invalidRequest("Unknown field '%s' in value of user defined type %s",
                                         fieldName,
                                         ut.getNameAsString());

                AbstractType<?> fieldType = ut.fieldType(fieldPosition);
                factories.put(fieldName,
                              raw.right.prepare(cfm).newSelectorFactory(cfm, fieldType, defs, boundNames));
            }

            return UserTypeSelector.newFactory(expectedType, factories);
        }

View on GitHub (pinned to 88fd0f6a0e)