xai-org/x-algorithm · error · UnsupportedOperationException

Unknown tag %d

Error message

Unknown tag %d

What it means

The Serializer's tag-dispatching deserialize switch hit a numeric tag it has no case for. Serializer deserializes values by inspecting a tag byte/short that identifies the value's kind (primitive, list, map, thrift struct, etc.); any tag outside the known set reaches the default branch and throws UnsupportedOperationException. This almost always means serialized data was produced by a newer/older Serializer version with additional types, or the payload is corrupted/misaligned.

Source

Thrown at botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java:733

              thriftOf((Class<? extends TBase>) tbaseClazz);
          return tbaseSerializer.deserialize(prot, false);

        case tagTEnum:
          String tenumClassName = prot.readString();
          Class<?> tenumClazz = ClassCache.forName(tenumClassName);
          Serializer tenumSerializer =
              thriftEnumOf((Class<? extends TEnum>) tenumClazz);
          return tenumSerializer.deserialize(prot, false);

        case tagThriftStruct:
          String tstructClassName = prot.readString();
          Class<?> tstructClazz = ClassCache.forName(tstructClassName);
          Serializer tstructSerializer =
              thriftStructOf((Class<? extends ThriftStruct>) tstructClazz);
          return tstructSerializer.deserialize(prot, false);

        default:
          throw new UnsupportedOperationException(
              String.format("Unknown tag %d", tag)
          );
      }
    }

    @Override
    protected void toScript(GenScript script, Object value) throws Exception {
      if (value instanceof Boolean) {
        BOOLEAN.genScript(script, (Boolean) value);
      } else if (value instanceof String) {
        STRING.genScript(script, (String) value);
      } else if (value instanceof ByteBuffer) {
        BINARY.genScript(script, (ByteBuffer) value);
      } else if (value instanceof Float) {
        DOUBLE.genScript(script, ((Float) value).doubleValue());
      } else if (value instanceof Double) {
        DOUBLE.genScript(script, (Double) value);
      } else if (value instanceof Long) {

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Verify the serialized payload was produced by the same Serializer version/schema that is reading it (check for version skew between writer and reader).
  2. Inspect the tag value in the exception and compare with the case labels in Serializer's deserialize switch to see which type is missing.
  3. Re-serialize the data with the current version, or regenerate the payload from source rather than reusing stale cached bytes.
  4. If a new type was added, bump the format/protocol version and reject mismatched payloads explicitly instead of relying on the default branch.

Example fix

// before
Object v = serializer.deserialize(prot, false);

// after
int tag = prot.readI32(); // or however the tag is read
if (!SUPPORTED_TAGS.contains(tag)) {
  throw new IllegalArgumentException("Incompatible serialized payload, tag=" + tag);
}
Object v = serializer.deserialize(prot, false);
Defensive patterns

Strategy: validation

Validate before calling

int tag = peekTag(prot);
if (!KNOWN_TAGS.contains(tag)) {
  throw new IllegalArgumentException("Refusing to deserialize unknown tag " + tag);
}

Try / catch

catch (UnsupportedOperationException e) {
  log.warn("payload/tag mismatch: {}", e.getMessage());
  // drop stale payload and regenerate
}

Prevention

When it happens

Trigger: Calling serializer.deserialize(prot, false) on a protocol stream whose next tag is not one of the tags handled in the switch; e.g. deserializing data written by a different schema or reading at the wrong offset.

Common situations: Version skew between the compiler that produced the serialized representation and the one reading it; corrupted or truncated payloads; manually constructed protocol input; adding a new type tag without updating old readers.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/5a1dfa31bbc0d2df. Report an issue: GitHub.