{"record":{"id":"0ea487247bc25da0","repo":"apache/iceberg","slug":"not-a-struct-type-this","errorCode":null,"errorMessage":"Not a struct type: + this","messagePattern":"Not a struct type: \\+ this","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/types/Type.java","lineNumber":77,"sourceCode":"    }\n\n    public Class<?> javaClass() {\n      return javaClass;\n    }\n  }\n\n  TypeID typeId();\n\n  default boolean isPrimitiveType() {\n    return false;\n  }\n\n  default PrimitiveType asPrimitiveType() {\n    throw new IllegalArgumentException(\"Not a primitive type: \" + this);\n  }\n\n  default Types.StructType asStructType() {\n    throw new IllegalArgumentException(\"Not a struct type: \" + this);\n  }\n\n  default Types.ListType asListType() {\n    throw new IllegalArgumentException(\"Not a list type: \" + this);\n  }\n\n  default Types.MapType asMapType() {\n    throw new IllegalArgumentException(\"Not a map type: \" + this);\n  }\n\n  default Types.VariantType asVariantType() {\n    throw new IllegalArgumentException(\"Not a variant type: \" + this);\n  }\n\n  default boolean isNestedType() {\n    return false;\n  }\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/types/Type.java#L59-L95","documentation":"Type.asStructType() narrows a Type to Types.StructType; the default implementation throws IllegalArgumentException because only struct types override it. It signals that the code attempted struct-level access (fields()) on a non-struct type.","triggerScenarios":"Calling asStructType() on a ListType, MapType, primitive, or VariantType — commonly inside projection, select, project, or reassignIds-style logic that assumed a field's type was a struct.","commonSituations":"Building row projections where a column is actually a list/map at the top level; visitor code handling nested types without checking the kind; renaming/refactoring that changed a field from struct to list.","solutions":["Guard with type.isStructType() or instanceof Types.StructType before narrowing.","Use TypeUtil.visit / TypeVisitor to handle each type kind explicitly.","Correct the field path or schema assumption that led to a non-struct type."],"exampleFix":"// before\nTypes.StructType st = schema.asStruct().field(\"tags\").type().asStructType();\n// after\nType tags = schema.asStruct().field(\"tags\").type();\nTypes.StructType st = tags instanceof Types.StructType ? (Types.StructType) tags : null;","handlingStrategy":"type-guard","validationCode":"Preconditions.checkArgument(type.isStructType(), \"Expected struct, got: %s\", type);","typeGuard":"if (type instanceof Types.StructType) {\n  Types.StructType st = (Types.StructType) type;\n}","tryCatchPattern":"try {\n  Types.StructType st = type.asStructType();\n} catch (IllegalArgumentException e) {\n  // non-struct path\n}","preventionTips":["Use instanceof Types.StructType checks before struct access.","Handle all nested kinds (struct/list/map/variant) in traversal code.","Re-verify assumptions after schema evolution changes field types."],"tags":["types","iceberg","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}