apache/cassandra · critical · AssertionError

Unsupported Verb Kind: + v.kind + for verb + v

Error message

Unsupported Verb Kind: + v.kind + for verb + v

What it means

During the static Verb registry sweep, an unknown Kind falls outside the switch over built-in kinds (with a CUSTOM case) and triggers AssertionError. The sweep computes min/max ids to detect overlapping id allocations between built-in and custom verbs.

Solutions

  1. Add a case for the new Kind in the id-range computation block in Verb's static initializer
  2. Verify every verb's kind is one of the enumerated Kind values
  3. Run startup tests after introducing new Kind values to catch unhandled switches

Example fix

// before
case CUSTOM: minCustom = Math.min(v.id, minCustom); break;
default: throw new AssertionError(...);
// after
case CUSTOM: minCustom = Math.min(v.id, minCustom); break;
case NEW_KIND: /* handle id range */ break;
default: throw new AssertionError(...);
Defensive patterns

Strategy: validation

Validate before calling

for (Verb v : Verb.values()) { switch (v.kind) { case ... /* mirror the static switch */ default: throw new IllegalStateException("unhandled kind " + v.kind); } }

Prevention

When it happens

Trigger: Adding a new Kind to the Verb enum without extending the static-id-computation switch; a verb whose kind field is null or corrupted so it matches no case.

Common situations: Extending Verb.Kind for new message classes and forgetting to update every switch over Kind; typically caught immediately at class initialization.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/net/Verb.java:611

    private static final int minCustomId;

    static
    {
        Verb[] verbs = values();
        int max = -1;
        int minCustom = Integer.MAX_VALUE;
        for (Verb v : verbs)
        {
            switch (v.kind)
            {
                case NORMAL:
                    max = Math.max(v.id, max);
                    break;
                case CUSTOM:
                    minCustom = Math.min(v.id, minCustom);
                    break;
                default:
                    throw new AssertionError("Unsupported Verb Kind: " + v.kind + " for verb " + v);
            }
        }
        minCustomId = minCustom;

        if (minCustom <= max)
            throw new IllegalStateException("Overlapping verb ids are not allowed");

        Verb[] idMap = new Verb[max + 1];
        int customCount = minCustom < Integer.MAX_VALUE ? CUSTOM_VERB_START - minCustom : 0;
        Verb[] customIdMap = new Verb[customCount + 1];
        for (Verb v : verbs)
        {
            switch (v.kind)
            {
                case NORMAL:
                    if (idMap[v.id] != null)
                        throw new IllegalArgumentException("cannot have two verbs that map to the same id: " + v + " and " + idMap[v.id]);
                    idMap[v.id] = v;

View on GitHub (pinned to 88fd0f6a0e)