xai-org/x-algorithm · error · SemanticCheckFailure
expect a FieldAccessibleType, but %s received
Error message
expect a FieldAccessibleType, but %s received
What it means
FieldAccessor.mkFieldAccessor throws SemanticCheckFailure when the root node's return type is not a FieldAccessibleType (i.e. not a thrift struct/union/map-like type with accessible fields). Field access paths like a.b.c require the base expression to be field-accessible.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/function/thrift/FieldAccessor.java:47
protected CacheLevel getCacheLevel() {
return CacheLevel.Global;
}
private static ASTNode.Signature getSignature(ASTNode node, Type valueType) {
return new ASTNode.Signature(ImmutableList.of(node.getReturnType()), valueType);
}
@SuppressWarnings("unchecked")
public static ASTNode mkFieldAccessor(
String exprText,
ASTNode node,
ImmutableList<String> fields
) throws SemanticCheckFailure {
if (!(node.getReturnType() instanceof FieldAccessibleType)) {
throw new SemanticCheckFailure(
String.format("expect a FieldAccessibleType, but %s received",
node.getReturnType().toString())
);
}
List<Tuple3<FieldAccessibleType, Type, Function<Object, Object>>> fieldInfosBuilder =
Lists.newArrayListWithCapacity(fields.size());
FieldAccessibleType objType = (FieldAccessibleType) node.getReturnType();
for (String field : fields.subList(0, fields.size() - 1)) {
Tuple3<FieldAccessibleType, Type, Function<Object, Object>> fieldInfo =
getFieldInfo(objType, field);
fieldInfosBuilder.add(fieldInfo);
if (!(fieldInfo.getSecond() instanceof FieldAccessibleType)) {
throw new SemanticCheckFailure(
String.format("expect a FieldAccessibleType, but %s received",
fieldInfo.getSecond().toString())
);
}View on GitHub (pinned to 24c60942c5)
Solutions
- Check the base expression's return type and fix it to produce a thrift struct/FieldAccessibleType
- If the type changed after a schema update, regenerate/refresh the type definitions
- Verify you passed the intended node (not a child/constant) to toFieldAccessor
Example fix
// before FieldAccessor.mkFieldAccessor(constantNode, fields); // returns String -> failure // after FieldAccessor.mkFieldAccessor(structNode, fields); // returns thrift struct type
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(node.getReturnType() instanceof FieldAccessibleType)) {
throw new IllegalArgumentException("base expression is not field-accessible: " + node.getReturnType());
} Type guard
public static boolean isFieldAccessible(ASTNode n) {
return n.getReturnType() instanceof FieldAccessibleType;
} Try / catch
try {
return FieldAccessor.mkFieldAccessor(node, fields);
} catch (SemanticCheckFailure e) {
// log base type and field path, fail expression compilation with context
} Prevention
- Check getReturnType() instanceof FieldAccessibleType before building accessors
- Keep a registry of base expressions and their expected thrift struct types
- Re-run semantic checks after thrift schema regeneration
When it happens
Trigger: Applying toFieldAccessor to a node whose getReturnType() is a primitive, string, or collection, e.g. building a field accessor over a Constant or over a numeric expression.
Common situations: Typos in field paths, accessing fields on scalar intermediates, schema changes that made the base type non-struct, or wiring the wrong source node into the accessor.
Related errors
- field name %s has to be a String.
- field %s expects %s type but %s received.
- Failed to create serializer for ThriftStruct %s: %s
- unknown struct value
- Class %s is not assignable from %s for field %s
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/255eea275d1393e7.
Report an issue: GitHub.