{"record":{"id":"298b883ba0ec8edb","repo":"apache/iceberg","slug":"cannot-parse-predicates-in-where-option-where-298b88","errorCode":null,"errorMessage":"Cannot parse predicates in where option: ${where}","messagePattern":"Cannot parse predicates in where option: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/procedures/BaseProcedure.java","lineNumber":198,"sourceCode":"    String tableName = Spark3Util.quotedFullIdentifier(tableCatalog().name(), tableIdent);\n    return spark().read().options(options).table(tableName);\n  }\n\n  protected void refreshSparkCache(Identifier ident, Table table) {\n    CacheManager cacheManager = spark.sharedState().cacheManager();\n    DataSourceV2Relation relation =\n        DataSourceV2Relation.create(table, Option.apply(tableCatalog), Option.apply(ident));\n    cacheManager.recacheByPlan(spark, relation);\n  }\n\n  protected Expression filterExpression(Identifier ident, String where) {\n    try {\n      String name = Spark3Util.quotedFullIdentifier(tableCatalog.name(), ident);\n      org.apache.spark.sql.catalyst.expressions.Expression expression =\n          SparkExpressionConverter.collectResolvedSparkExpression(spark, name, where);\n      return SparkExpressionConverter.convertToIcebergExpression(expression);\n    } catch (AnalysisException e) {\n      throw new IllegalArgumentException(\"Cannot parse predicates in where option: \" + where, e);\n    }\n  }\n\n  protected InternalRow newInternalRow(Object... values) {\n    return new GenericInternalRow(values);\n  }\n\n  protected static class Result implements LocalScan {\n    private final StructType readSchema;\n    private final InternalRow[] rows;\n\n    public Result(StructType readSchema, InternalRow[] rows) {\n      this.readSchema = readSchema;\n      this.rows = rows;\n    }\n\n    @Override\n    public StructType readSchema() {","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/procedures/BaseProcedure.java#L180-L216","documentation":"BaseProcedure.filterExpression converts a user-supplied 'where' predicate string into an Iceberg Expression. It first asks Spark to parse and resolve the SQL expression; if Spark raises AnalysisException (unparseable or unresolvable predicate), it rethrows as IllegalArgumentException. The error means the procedure's where option is not a valid, resolvable SQL predicate.","triggerScenarios":"Passing where => \"ts > '2024-01-01'\" where the column doesn't exist, types don't match, syntax is invalid, or the predicate references columns/relations Spark cannot resolve during collectResolvedSparkExpression.","commonSituations":"Comparing a timestamp column with a non-castable string; using functions unsupported in the resolved context; referencing partition/column names with wrong case or quoting; typos like where => \"a == 1 AND\".","solutions":["Validate the predicate runs as a plain Spark query first: SELECT count(*) FROM tbl WHERE <predicate>.","Cast literal types explicitly, e.g. ts > cast('2024-01-01' as timestamp).","Fully qualify column names if the predicate needs disambiguation.","Quote identifiers containing special characters with backticks."],"exampleFix":"-- before\nCALL iceberg.system.expire_snapshots(table => 'db.t', where => \"ts > '2024-01-01'\");\n-- after\nCALL iceberg.system.expire_snapshots(table => 'db.t', where => \"ts > cast('2024-01-01' as timestamp)\");","handlingStrategy":"validation","validationCode":"spark.sql(s\"SELECT 1 FROM $table WHERE $where\").limit(1).collect() // dry-run the predicate","typeGuard":null,"tryCatchPattern":"try { CALL ... where => \"...\"; } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Cannot parse predicates\")) { /* fix predicate */ } else throw e; }","preventionTips":["Test predicates as plain Spark SQL first.","Cast literal strings to the column's type explicitly.","Avoid referencing functions/columns not resolvable against the target table."],"tags":["spark","predicate","sql-parse"],"backgroundTag":"invalid-argument-format","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"}