{"record":{"id":"50dc9a0a7ad5ad99","repo":"apache/iceberg","slug":"unsupported-runtime-filter-50dc9a","errorCode":null,"errorMessage":"Unsupported runtime filter {}","messagePattern":"Unsupported runtime filter (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkCopyOnWriteScan.java","lineNumber":141,"sourceCode":"        // so filter files only if it is beneficial\n        if (filteredLocations == null || fileLocations.size() < filteredLocations.size()) {\n          this.filteredLocations = fileLocations;\n          List<FileScanTask> filteredTasks =\n              tasks().stream()\n                  .filter(file -> fileLocations.contains(file.file().location()))\n                  .collect(Collectors.toList());\n\n          LOG.info(\n              \"{} of {} task(s) for table {} matched runtime file filter with {} location(s)\",\n              filteredTasks.size(),\n              tasks().size(),\n              table().name(),\n              fileLocations.size());\n\n          resetTasks(filteredTasks);\n        }\n      } else {\n        LOG.warn(\"Unsupported runtime filter {}\", predicate);\n      }\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }\n\n    SparkCopyOnWriteScan that = (SparkCopyOnWriteScan) o;\n    return table().name().equals(that.table().name())\n        && readSchema().equals(that.readSchema()) // compare Spark schemas to ignore field ids\n        && filterExpressions().toString().equals(that.filterExpressions().toString())","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkCopyOnWriteScan.java#L123-L159","documentation":"SparkCopyOnWriteScan implements runtime filtering for copy-on-write deletes; when filter() receives a predicate that SparkV2Filters cannot convert to an Iceberg expression, it warns and ignores that predicate. Other convertible filters in the same call still apply, and scan correctness is unaffected.","triggerScenarios":"Spark passes a runtime predicate with an unsupported function/type to SparkCopyOnWriteScan.filter during delete-file planning.","commonSituations":"Newer Spark runtime filter functions not yet mapped in SparkV2Filters; custom predicates applied during MERGE/DELETE planning on CoW tables.","solutions":["No correctness action needed; the filter is simply not used to prune delete files.","Confirm which predicate was unsupported and whether a supported equivalent exists.","Upgrade the Iceberg Spark runtime for broader SparkV2Filters coverage."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":"if (SparkV2Filters.convert(predicate) == null) { /* unsupported for CoW delete planning */ }","tryCatchPattern":null,"preventionTips":["Restrict delete/merge conditions to supported comparisons when CoW performance matters.","Upgrade connector versions for broader predicate conversion support.","Monitor planning time; unpruned delete files signal skipped runtime filters."],"tags":["spark","runtime-filter","copy-on-write","pushdown"],"backgroundTag":"unsupported-operation","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"}