apache/cassandra · error · SyntaxException

Syntax error parsing

Error message

Syntax error parsing '%s' at char %d: %s

What it means

TypeParser.throwSyntaxError is the shared helper that raises a SyntaxException carrying the full input string, current character index, and a specific reason (unexpected character, bad alias, invalid hex, expecting ':' or '=>' token, etc.). It is the canonical 'malformed type string' error in Cassandra's type parser.

Solutions

  1. Read the reason suffix after 'at char N:' in the message — it names the exact problem (unexpected character, expecting ':' token, bad alias, hex error)
  2. Go to that character index in the string and fix the token: use '=>' for aliases, ':' for field separators, valid even-length hex for keys
  3. Validate the whole type string with AbstractType.parse() in a scratch environment before applying schema changes
  4. Regenerate complex type strings programmatically (e.g. via stringifyTKeyValueParameters) instead of concatenating them by hand

Example fix

// before
TypeParser.parse("DynamicCompositeType(a = UTF8Type)"); // '=>' expected
// after
TypeParser.parse("DynamicCompositeType(a => UTF8Type)");
Defensive patterns

Strategy: try-catch

Validate before calling

static void preflightTypeString(String s) {
    if (s == null || s.isEmpty()) return;
    int depth = 0;
    for (char c : s.toCharArray()) {
        if (c == '(') depth++;
        else if (c == ')') depth--;
        if (depth < 0) throw new IllegalArgumentException("Unbalanced ')'");
    }
    if (depth != 0) throw new IllegalArgumentException("Unclosed '('");
}

Try / catch

try {
    AbstractType<?> t = TypeParser.parse(typeString);
} catch (SyntaxException e) {
    // message format: Syntax error parsing '<str>' at char <idx>: <reason>
    int idx = Integer.parseInt(e.getMessage().replaceAll(".*at char (\\d+):.*", "$1"));
    throw new SchemaConfigurationException("Bad token in type string near index " + idx + ": " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Any of getKeyValueParameters, getAliasParameters, getCollectionsParameters, fromHex, or getUserTypeParameters encountering an unexpected token: e.g. DynamicCompositeType(a!UTF8Type) (unexpected character '!'), an alias longer than one char, invalid hex bytes, or a missing ':' between a field name and type in a UTD/collections parameter list.

Common situations: Hand-written comparator strings with typos, using '=' instead of '=>' in DynamicCompositeType aliases, odd-length or non-hex key strings, missing colons in UserType field definitions, copy-pasted type strings with smart quotes or stray whitespace characters.

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/ea7f14c2aec36a31. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/db/marshal/TypeParser.java:539

        {
            Method method = typeClass.getDeclaredMethod("getInstance", TypeParser.class);
            return (AbstractType<?>) method.invoke(null, parser);
        }
        catch (NoSuchMethodException | IllegalAccessException e)
        {
            throw new ConfigurationException("Invalid comparator class " + typeClass.getName() + ": must define a public static instance field or a public static method getInstance(TypeParser).");
        }
        catch (InvocationTargetException e)
        {
            ConfigurationException ex = new ConfigurationException("Invalid definition for comparator " + typeClass.getName() + ".");
            ex.initCause(e.getTargetException());
            throw ex;
        }
    }

    private void throwSyntaxError(String msg) throws SyntaxException
    {
        throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: %s", str, idx, msg));
    }

    private boolean isEOS()
    {
        return isEOS(str, idx);
    }

    private static boolean isEOS(String str, int i)
    {
        return i >= str.length();
    }

    private static boolean isBlank(int c)
    {
        return c == ' ' || c == '\t' || c == '\n';
    }

    private void skipBlank()

View on GitHub (pinned to 88fd0f6a0e)