xai-org/x-algorithm · error · TException

unknown struct value

Error message

unknown struct value

What it means

TBotMakerMapProtocol.readStructBegin dispatches on the runtime value: Maps push a MapStructScope and ThriftStruct values push a ThriftStructScope. Any other value type throws TException 'unknown struct value'.

Source

Thrown at botmaker/src/java/com/twitter/botmaker/compiler/types/ThriftStructType.java:713

    public void readMessageEnd() throws TException {
      throw new TException(new UnsupportedOperationException());
    }

    @Override
    public TStruct readStructBegin() throws TException {
      if (!scopes.empty()) {
        Scope scope = scopes.peek();
        ThriftStructMetaData structMetadata = (ThriftStructMetaData) scope.getMetaData();
        ThriftStructType thriftType = ofThriftStruct(structMetadata.structClass);
        Object value = readValue();
        if (value instanceof Map) {
          Map<Object, Object> mapValue = (Map<Object, Object>) value;
          scopes.push(new MapStructScope(thriftType.metadataMap, mapValue));
        } else if (value instanceof ThriftStruct) {
          ThriftStruct structValue = (ThriftStruct) value;
          scopes.push(new ThriftStructScope(thriftType, structValue));
        } else {
          throw new TException("unknown struct value");
        }
      } else {
        scopes.push(new MapStructScope(metadataMap, data));
      }

      return null;
    }

    @Override
    public void readStructEnd() {
      scopes.pop();
    }

    @Override
    public TField readFieldBegin() {
      StructScope scope = (StructScope) scopes.peek();
      return scope.readField();
    }

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Ensure nested struct values are Maps or scrooge ThriftStruct instances before writing
  2. Convert TBase objects to Maps or the corresponding ThriftStruct type
  3. Validate the value tree shape against the expected thrift schema before serialization

Example fix

// before
map.put("nested", tBaseObj); // TBase not ThriftStruct
// after
map.put("nested", structTupleOrMapValue); // Map<String,Object> or ThriftStruct
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(v instanceof Map) && !(v instanceof ThriftStruct)) {
  throw new IllegalArgumentException("nested struct value must be Map or ThriftStruct");
}

Type guard

boolean isStructValue(Object v) { return v instanceof Map || v instanceof ThriftStruct; }

Try / catch

catch TException 'unknown struct value' and pinpoint the offending path in the value tree

Prevention

When it happens

Trigger: Writing a struct-typed value whose runtime object is neither a Map nor a ThriftStruct — e.g. an apache-thrift TBase object, a scala case class, or a JSON primitive placed where a nested struct is expected.

Common situations: Feeding botmaker a hand-built value tree (e.g. parsed JSON or test fixtures) where nested struct fields contain non-struct objects; mixing apache-thrift TBase values with scrooge-based botmaker serialization.

Related errors


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