{"record":{"id":"e3abd4b3dba996cc","repo":"apache/iceberg","slug":"notstartswith-expression-is-not-supported-by-the-v","errorCode":null,"errorMessage":"notStartsWith expression is not supported by the visitor","messagePattern":"notStartsWith expression is not supported by the visitor","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/expressions/ExpressionVisitors.java","lineNumber":125,"sourceCode":"    public <T> R notEq(BoundReference<T> ref, Literal<T> lit) {\n      return null;\n    }\n\n    public <T> R in(BoundReference<T> ref, Set<T> literalSet) {\n      throw new UnsupportedOperationException(\"In expression is not supported by the visitor\");\n    }\n\n    public <T> R notIn(BoundReference<T> ref, Set<T> literalSet) {\n      throw new UnsupportedOperationException(\"notIn expression is not supported by the visitor\");\n    }\n\n    public <T> R startsWith(BoundReference<T> ref, Literal<T> lit) {\n      throw new UnsupportedOperationException(\n          \"startsWith expression is not supported by the visitor\");\n    }\n\n    public <T> R notStartsWith(BoundReference<T> ref, Literal<T> lit) {\n      throw new UnsupportedOperationException(\n          \"notStartsWith expression is not supported by the visitor\");\n    }\n\n    /**\n     * Handle a non-reference value in this visitor.\n     *\n     * <p>Visitors that require {@link BoundReference references} and not {@link Bound terms} can\n     * use this method to return a default value for expressions with non-references. The default\n     * implementation will throw a validation exception because the non-reference is not supported.\n     *\n     * @param term a non-reference bound expression\n     * @param <T> a Java return type\n     * @return a return value for the visitor\n     */\n    public <T> R handleNonReference(Bound<T> term) {\n      throw new ValidationException(\"Visitor %s does not support non-reference: %s\", this, term);\n    }\n","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/expressions/ExpressionVisitors.java#L107-L143","documentation":"The base visitor's default notStartsWith(BoundReference, Literal) throws UnsupportedOperationException; NOT STARTS_WITH predicates are only handled by visitors that override this method. Thrown when a notStartsWith predicate is visited without an override.","triggerScenarios":"Visiting Expressions.notStartsWith(col, \"prefix\") with a visitor lacking a notStartsWith override — commonly custom evaluators or engine integrations predating the predicate.","commonSituations":"Pushing NOT LIKE 'abc%' filters into older visitor implementations; evaluators updated for startsWith but not its negation.","solutions":["Override notStartsWith(BoundReference<T> ref, Literal<T> lit) in the visitor (typically the negation of the startsWith result)","Rewrite the expression with Expressions.rewriteNot so notStartsWith is expressed via supported forms, or fall back conservatively","Upgrade the evaluator to a version that supports notStartsWith"],"exampleFix":"// before\n// no notStartsWith override -> default throws\n// after\n@Override\npublic <T> R notStartsWith(BoundReference<T> ref, Literal<T> lit) {\n  return not(startsWithResult(ref, lit));\n}","handlingStrategy":"try-catch","validationCode":"boolean hasNotStartsWith = exprOpScan(expr, op -> op == Expression.Operation.NOT_STARTS_WITH);","typeGuard":"static boolean isNotStartsWith(Predicate p) { return p.op() == Expression.Operation.NOT_STARTS_WITH; }","tryCatchPattern":"try {\n  return visitor.notStartsWith(ref, lit);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"notStartsWith expression is not supported\")) {\n    return not(visitor.startsWith(ref, lit));\n  }\n  throw e;\n}","preventionTips":["Override notStartsWith whenever startsWith is implemented","Run Expressions.rewriteNot on filters before evaluating with limited visitors","Include NOT LIKE prefix filters in evaluator test matrices"],"tags":["java","expressions","visitor","string-prefix"],"backgroundTag":"method-not-implemented","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}