xai-org/x-algorithm · error · UnsupportedOperationException

Unsupported type %s to fingerprint.

Error message

Unsupported type %s to fingerprint.

What it means

The generic fingerprinting entry point (Serializer.computeFingerprint) only knows how to hash certain value shapes: values with a matching registered Serializer and ThriftStruct instances. Any other runtime class hits UnsupportedOperationException with the class name, so fingerprints cannot silently diverge for unhandled types.

Source

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

        Tuple tuple = (Tuple) value;
        Type[] typeParams = new Type[tuple.size()];
        Arrays.fill(typeParams, Type.OBJECT);
        Serializer<Tuple> tupleSerializer = tupleOf(typeParams);
        tupleSerializer.computeFingerprint(hasher, (Tuple) value);
      } else if (value instanceof TBase) {
        Class<? extends TBase> clazz = (Class<? extends TBase>) value.getClass();
        Serializer serializer = thriftOf(clazz);
        serializer.computeFingerprint(hasher, value);
      } else if (value instanceof TEnum) {
        Class<? extends TEnum> clazz = (Class<? extends TEnum>) value.getClass();
        Serializer serializer = thriftEnumOf(clazz);
        serializer.computeFingerprint(hasher, value);
      } else if (value instanceof ThriftStruct) {
        Class<? extends ThriftStruct> clazz = (Class<? extends ThriftStruct>) value.getClass();
        Serializer serializer = thriftStructOf(clazz);
        serializer.computeFingerprint(hasher, value);
      } else {
        throw new UnsupportedOperationException(
            String.format("Unsupported type %s to fingerprint.", value.getClass().getName())
        );
      }
    }

    @Override
    protected void serialize(TProtocol prot, Object value) throws Exception {
      if (value instanceof Boolean) {
        prot.writeByte(tagBoolean);
        BOOLEAN.serialize(prot, (Boolean) value, false);
      } else if (value instanceof String) {
        prot.writeByte(tagString);
        STRING.serialize(prot, (String) value, false);
      } else if (value instanceof ByteBuffer) {
        prot.writeByte(tagBinary);
        BINARY.serialize(prot, (ByteBuffer) value, false);
      } else if (value instanceof Float) {
        prot.writeByte(tagFloat);

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Register/implement a Serializer<Foo> for the offending class named in the message
  2. Convert the value to an already-supported type (String, Long, ThriftStruct, etc.) before fingerprinting
  3. If the field should not participate in the fingerprint, exclude it from the hashed value

Example fix

// before
hasher = Serializer.computeFingerprint(hasher, myPojo); // UnsupportedOperationException

// after
Serializer<MyPojo> S = new Serializer<MyPojo>() { /* implement fingerprint/serialize */ };
hasher = S.computeFingerprint(hasher, myPojo);
Defensive patterns

Strategy: validation

Validate before calling

// Only fingerprint values you know are supported
boolean fingerprintable(Object v) {
  return v == null || v instanceof ThriftStruct || hasRegisteredSerializer(v.getClass());
}

Type guard

boolean hasRegisteredSerializer(Class<?> c) {
  return Serializer.registryLookup(c) != null; // however your wiring exposes it
}

Try / catch

try {
  Serializer.computeFingerprint(hasher, value);
} catch (UnsupportedOperationException e) {
  // convert to string form as a stable fallback or fail fast with schema error
}

Prevention

When it happens

Trigger: Passing a value whose class has no registered Serializer and is not a ThriftStruct — e.g. a plain POJO, java.util.Date, or a custom type not wired into the serializer registry — into computeFingerprint.

Common situations: Adding a new field type to a fingerprinted struct without registering a Serializer for it; refactors that swap a field from a Thrift type to a plain class.

Related errors


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