# \`waitall(tasks)\` doesn't throw as \`foreach(wait, tasks)\` does

**URL:** <https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 18, 2025, 1:51pm UTC](https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260 "2025-10-18T13:51:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 18, 2025, 1:51pm UTC](https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260/1 "2025-10-18T13:51:40Z")

</div>

I have a `tasks` which is a vector of Tasks.

If I use `foreach(wait, tasks)`, then it will throw like this (which is expected behavior)

```julia
julia> fill_model_D_X!(inn, X)
 rest = 1, j = 40304412
Warning: 1.760797410756771e9 terminate all solves
ERROR: TaskFailedException
Stacktrace:
 [1] #wait#582
   @ ./task.jl:363 [inlined]
 [2] wait
   @ ./task.jl:360 [inlined]
 [3] foreach
   @ ./abstractarray.jl:3188 [inlined]
 [4] fill_model_D_X!(v::Vector{JuMP.Model}, X::Vector{NamedTuple})
   @ Main ./REPL[40]:38
 [5] top-level scope
   @ REPL[59]:1

    nested task error: UNKNOWN_RESULT_STATUSINTERRUPTED
    Stacktrace:
     [1] error(s::String)
       @ Base ./error.jl:44
     [2] get_a_paired_block(O::Vector{Int64})
       @ Main ./REPL[25]:53
     [3] (::var"#fill_model_D_X!##0#fill_model_D_X!##1"{Vector{…}, Vector{…}, Base.Threads.Atomic{…}})(j::Int64)
       @ Main ./REPL[40]:5
     [4] (::var"#fill_model_D_X!##4#fill_model_D_X!##5"{Int64, var"#fill_model_D_X!##0#fill_model_D_X!##1"{…}})()
       @ Main ./REPL[40]:14

```

However, If I just replace it with `waitall(tasks)`, then the ERROR is not seen (which should exists).

```julia
julia> fill_model_D_X!(inn, X) # No ERROR here
 rest = 1, j = 50990457
Warning: 1.760797120923299e9 terminate all solves 

julia> for i = X # But it is indeed problematic, if I check it manually
       end
ERROR: UndefRefError: access to undefined reference

```

I want to ask: is this normal? Why?

And, what’s the advantage of using `waitall` in favor of the old alternatives?

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [October 18, 2025, 2:57pm UTC](https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260/2 "2025-10-18T14:57:22Z")

</div>

It should work with `throw=true`, but it doesn’t.

```julia-auto

julia> t1 = Threads.@spawn (sleep(2); 1 ÷ 1)
Task (runnable, started) @0x00007426bcca6b30

julia> t2 = Threads.@spawn (sleep(2); 1 ÷ 0)
Task (runnable, started) @0x00007426bcca6d10

julia> waitall([t1,t2], throw=true)
(Task[Task (done) @0x00007426bcca6b30, Task (failed) @0x00007426bcca6d10], Task[])

julia> fetch(t1)
1

julia> fetch(t2)
ERROR: TaskFailedException

```

You should enter an issue at github.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 18, 2025, 10:44pm UTC](https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260/3 "2025-10-18T22:44:19Z")

</div>

It’s here.

> <https://github.com/JuliaLang/julia/issues/59901#issue-3529293892>
>
> It doesn't throw like \`foreach(wait, tasks)\`, is this normal?
> \`\`\`julia
> julia\> f(…d) = 1 ÷ d;
> 
> julia\> waitall(Threads.@spawn(f(i)) for i = 0:1) # no error
> (Task\[Task (failed) @0x00007ced9879eb30, Task (done) @0x00007ced9879ec20\], Task\[\])
> \`\`\`
> (found in https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260?u=waltermadelim)

---

<div class="post-metadata">

**Author:** ![mrkn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrkn/32/7213_2.png) [@mrkn](https://discourse.julialang.org/u/mrkn)\
**Post date:** [October 20, 2025, 11:37am UTC](https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260/4 "2025-10-20T11:37:59Z")

</div>

This bug is addressed in the following PR:

> <https://github.com/JuliaLang/julia/pull/59905>
>
> Closes #59901

> And, what’s the advantage of using `waitall` in favor of the old alternatives?

`waitall` supports the `failfast` and `throw` options. `foreach(wait, tasks)` is equivalent to `waitall(tasks)`, which is the same as `waitall(tasks; failfast=true, throw=true)`. You can wait for all tasks to complete, even if some tasks throw exceptions, by setting `failfast=false`. Alternatively, you can handle failed tasks the same way as successful ones by setting `throw=false`.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 20, 2025, 1:42pm UTC](https://discourse.julialang.org/t/waitall-tasks-doesnt-throw-as-foreach-wait-tasks-does/133260/5 "2025-10-20T13:42:03Z")

</div>

> [@mrkn](#):
>
> You can wait for all tasks to complete, even if some tasks throw exceptions, by setting `failfast=false`. Alternatively, you can handle failed tasks the same way as successful ones by setting `throw=false`

Well, to be honest I doubt if they are meaningful in practice. Because exceptions are severe to be eradicated for me. And throwing helps people debug.
