{"record":{"id":"bf633819877e9b2b","repo":"apache/iceberg","slug":"task-set-failed-with-an-uncaught-throwable","errorCode":null,"errorMessage":"Task set failed with an uncaught throwable","messagePattern":"Task set failed with an uncaught throwable","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/util/Tasks.java","lineNumber":278,"sourceCode":"              try {\n                abortTask.run(iterator.next());\n              } catch (Exception e) {\n                failed = true;\n                LOG.error(\"Failed to abort task\", e);\n                // keep going\n              }\n              if (stopAbortsOnFailure && failed) {\n                break;\n              }\n            }\n          }\n        }\n      }\n\n      if (throwFailureWhenFinished && !exceptions.isEmpty()) {\n        Tasks.throwOne(exceptions, exceptionClass);\n      } else if (throwFailureWhenFinished && threw) {\n        throw new RuntimeException(\"Task set failed with an uncaught throwable\");\n      }\n\n      return !threw;\n    }\n\n    private void tryRunOnFailure(I item, Exception failure) {\n      try {\n        onFailure.run(item, failure);\n      } catch (Exception failException) {\n        failure.addSuppressed(failException);\n        LOG.error(\"Failed to clean up on failure\", failException);\n        // keep going\n      }\n    }\n\n    private <E extends Exception> boolean runParallel(\n        final Task<I, E> task, Class<E> exceptionClass) throws E {\n      final Queue<I> succeeded = new ConcurrentLinkedQueue<>();","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/util/Tasks.java#L260-L296","documentation":"Tasks (single-threaded execution path) collects task failures; if a task threw a Throwable that is not an Exception (so it escaped the exception-collection logic, caught via 'threw'), and throwFailureWhenFinished is set and the exceptions list is empty, it throws this RuntimeException. It signals a non-Exception throwable (e.g. Error, or a Throwable subclass) killed the task set without being recorded as a normal failure.","triggerScenarios":"Running Tasks.foreach(...).throwFailureWhenFinished() where a task threw a Throwable that is not an Exception (e.g. StackOverflowError, NoClassDefFoundError, or a custom Throwable), bypassing the exceptions list.","commonSituations":"Classpath issues surfacing as Error during task execution; OOM/stack overflow inside task bodies; throwing Throwable subclasses from custom task implementations.","solutions":["Inspect the task's original stack trace/logs — this wrapper hides a non-Exception throwable; find the underlying Error","Fix the root cause (classpath, memory, or bad throwable usage in task code)","Ensure task code throws Exception/RuntimeException subtypes so failures are collected and reported via throwOne","If failures should be tolerated, drop throwFailureWhenFinished or add .suppress()/.retry() configuration"],"exampleFix":"// before\nTasks.foreach(items).throwFailureWhenFinished().run(item -> process(item)); // process throws Error\n// after\nTasks.foreach(items).throwFailureWhenFinished().run(item -> {\n  try { process(item); } catch (Throwable t) {\n    throw new RuntimeException(\"processing failed for \" + item, t); // surface as collected failure\n  }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"boolean ok = Tasks.foreach(items)\n  .suppress()\n  .run(task);\nif (!ok) { /* inspect logs for the non-Exception throwable */ }","preventionTips":["Throw Exception/RuntimeException subtypes from task bodies, never Throwable/Error","Monitor JVM Error conditions (OOM, stack overflow) in task threads","Keep the original task stack traces in logs","Use suppress()/retry() deliberately rather than relying on abort semantics"],"tags":["tasks","parallelism"],"backgroundTag":"internal-invariant-violation","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"}