{"record":{"id":"a0419e6a6e610a60","repo":"apache/iceberg","slug":"unsupported-term-term","errorCode":null,"errorMessage":"Unsupported term: ${term}","messagePattern":"Unsupported term: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/expressions/ExpressionUtil.java","lineNumber":247,"sourceCode":"  }\n\n  public static String describe(Term term) {\n    if (term instanceof UnboundTransform) {\n      return ((UnboundTransform<?, ?>) term).transform()\n          + \"(\"\n          + describe(((UnboundTransform<?, ?>) term).ref())\n          + \")\";\n    } else if (term instanceof BoundTransform) {\n      return ((BoundTransform<?, ?>) term).transform()\n          + \"(\"\n          + describe(((BoundTransform<?, ?>) term).ref())\n          + \")\";\n    } else if (term instanceof NamedReference) {\n      return ((NamedReference<?>) term).name();\n    } else if (term instanceof BoundReference) {\n      return ((BoundReference<?>) term).name();\n    } else {\n      throw new UnsupportedOperationException(\"Unsupported term: \" + term);\n    }\n  }\n\n  public static <T> UnboundTerm<T> unbind(BoundTerm<T> term) {\n    if (term instanceof BoundTransform) {\n      BoundTransform<?, T> bound = (BoundTransform<?, T>) term;\n      return Expressions.transform(bound.ref().name(), bound.transform());\n    } else if (term instanceof BoundReference) {\n      return Expressions.ref(((BoundReference<T>) term).name());\n    }\n\n    throw new UnsupportedOperationException(\"Cannot unbind unsupported term: \" + term);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> UnboundTerm<T> unbind(Term term) {\n    if (term instanceof UnboundTerm) {\n      return (UnboundTerm<T>) term;","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/expressions/ExpressionUtil.java#L229-L265","documentation":"ExpressionUtil's term-to-string helper (used by describe/sanitize/describe quoting) only knows NamedReference and BoundReference term types. Any other Term implementation passed to it hits this fallback UnsupportedOperationException. It signals an unhandled term variant in code that renders terms as strings.","triggerScenarios":"Calling ExpressionUtil.describe (or the sanitizing visitors that call it) with a Term that is neither NamedReference nor BoundReference, e.g. an UnboundTransform or a custom Term implementation.","commonSituations":"Custom expression extensions or new term types added in newer Iceberg versions but not yet handled by the describe helper; passing an UnboundTransform term from a transform expression into ExpressionUtil.describe; reflection-built terms from other modules.","solutions":["Check the actual runtime type of the term before calling describe (NamedReference/BoundReference only)","Upgrade Iceberg if using a new term type like UnboundTransform that a newer version handles","Use ExpressionUtil.describe(Expression) on the full expression instead of describing terms directly","If a custom Term was implemented, convert it to a supported reference or handle it before calling describe"],"exampleFix":"// before\nString desc = ExpressionUtil.describe(myUnboundTransformTerm);\n// after\nTerm ref = term instanceof UnboundTransform ? ((UnboundTransform<?, ?>) term).ref() : term;\nString desc = ExpressionUtil.describe(ref);","handlingStrategy":"type-guard","validationCode":"if (!(term instanceof NamedReference) && !(term instanceof BoundReference)) {\n  throw new IllegalArgumentException(\"describe() supports only named/bound references, got: \" + term.getClass());\n}","typeGuard":"boolean isDescribableTerm(Term t) {\n  return t instanceof NamedReference || t instanceof BoundReference;\n}","tryCatchPattern":"try { return ExpressionUtil.describe(term); }\ncatch (UnsupportedOperationException e) { return term != null ? term.toString() : \"<unknown term>\"; }","preventionTips":["Only pass NamedReference or BoundReference to ExpressionUtil.describe","Check Iceberg release notes for new term types before upgrading","Handle UnboundTransform terms by extracting .ref() first"],"tags":["expressions","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}