# Scoping rules try-catch inside a while loop

**URL:** <https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360>\
**Category:** General Usage\
**Created:** [October 22, 2025, 3:14pm UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360 "2025-10-22T15:14:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [October 22, 2025, 3:14pm UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/1 "2025-10-22T15:14:41Z")

</div>

Hi all,

I have a problem due to scoping rules of while loop and try-catch block. I have read similar topics on the forum, but the answers seems to be inapplicable in my case.

My problem is the following. I have a function that can fail due to numerical issues. When the function fails, I want to retry the calculation. This function returns a vector which dimension is not known a priori.

Here is my attempt:

```julia
function f(x, y)
  # x and y are vectors

  success = false
  stop = 0
  local z # z is a vector whose dimension is not known
  while !success && (stop < 10)
    try
       z = compute(x, y)
       success = true
   catch e
       @warn "Retry..."
       stop += 1
    end
  end

  if stop == 10
    error("Fail!")
  end

  return z
end

```

Such a code structure return the following error:

```julia
ERROR: UndefVarError: `z` not defined in local scope
Suggestion: check for an assignment to a local variable that shadows a global of the same name.

```

I understand why the problem arises, but I don’t figure out how to solve it.

Thank you for your help

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [October 22, 2025, 6:50pm UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/2 "2025-10-22T18:50:15Z")

</div>

Hi,

I don’t really understand the issue: your code already works as intended as far as I can tell (if you add the `while`’s `end`, and maybe also give the function a name, say `f`)? E.g. for `compute(x, y) = x + y`, `f(x, y)` returns `x + y` without issues, while for `compute(x, y) = error()`, `f(x, y)` throws the `"Fail!"` `error`, never reaching the `return z`.

> [@Maucejo](#):
>
> I have a function that can fail due to numerical issues. When the function fails, I want to retry the calculation.

By the way, note that if your function is deterministic, running it again won’t help with numerical issues. Of course, if you’re using RNG, or the order of operations might change due to thread scheduling, it might help.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [October 22, 2025, 9:55pm UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/3 "2025-10-22T21:55:09Z")

</div>

Start with the above commenter’s remarks. But if that doesn’t resolve all your issues, note that `try` introduces a new scope. I don’t have a REPL handy to test this (or whether it’s even necessary, since the above poster says what you had was almost fine), but if you run into problems you can try to instead retrieve values from the scope like so:

```julia
z, success = try
  c = compute(x, y) # you could name this `z`, but a different name is probably clearer
  c, true # will be assigned to the outer `z, success` when the result of this line is "returned" from this block
catch e
  # ...
  z, false # this probably works, but I haven't tested it. Sorry.
end

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 23, 2025, 1:46am UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/4 "2025-10-23T01:46:44Z")

</div>

It’s not clear how you’re running into that error. Could you provide a fully working example? That means that if anybody copies the code and runs it themselves, they’d see the same error you did. At minimum you need to provide `compute` and the call of that nameless function. If you can simplify `compute` to less code and dependencies without removing the error, you should.

> [@mikmoore](#):
>
> note that `try` introduces a new scope.

That shouldn’t matter, the `local z` line declares a local variable in that local scope level, and nested local scopes will reassign that same variable by default. That’s why eldee’s non-erroring `compute` worked.

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [October 23, 2025, 5:11am UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/5 "2025-10-23T05:11:05Z")

</div>

Sorry for the typos of the code. Actually, the actual function solves an over or underdetermined problems depending on the input data.

The MWE is representative of the actual code and it throws a scoping error despite the definition of the `local` variable.

---

<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 23, 2025, 6:04am UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/6 "2025-10-23T06:04:33Z")

</div>

I can’t reproduce the `UndefVarError`. It either works or throws an `ERROR: Fail!`.

```julia-auto
compute(x,y) = rand() < 0.9 ? error("Ouch!") : x+y

function f(x, y)
    success = false
    stop = 0
    local z # z is a vector whose dimension is not known
    while !success && (stop < 10)
        try
            z = compute(x, y)
            success = true
        catch e
            @warn "Retry..."
            stop += 1
        end
    end

    if stop == 10
        error("Fail!")
    end

    return z
end

julia> f(2,3)
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
5

julia> f(2,3)
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
┌ Warning: Retry...
└ @ Main ~/scratch/foo.jl:13
ERROR: Fail!
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:44
 [2] f(x::Int64, y::Int64)
   @ Main ~/scratch/foo.jl:19
 [3] top-level scope
   @ REPL[2]:1

```

Which version of julia are you running?

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [October 23, 2025, 6:49am UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/7 "2025-10-23T06:49:58Z")

</div>

I use Julia 1.12.1.

This code works perfectly as mine eventually 😅. I relaunch the code this morning and my function works. I don’t know what happened. My workspace and namespace may be too messy.

Thank you all!

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [October 23, 2025, 8:09am UTC](https://discourse.julialang.org/t/scoping-rules-try-catch-inside-a-while-loop/133360/8 "2025-10-23T08:09:31Z")

</div>

For reference, some strategies you could use when you’re not sure you will get a proper output `z`:

- Initialise `z` using a sentinel value (which `compute` would never return, e.g. `z = Float64[]`). If `compute` was successful, `z` will have been rebound to a proper value. The caller of `f` then determines for success by comparing the returned value to the sentinel value. You might have to be a bit careful with type stability (though a `Union` return type with two options, such as `Union{Vector{Float64}, Nothing}`, should be fine).
- Put `z` into a mutable container in which it can be undefined. E.g. `z = Base.RefValue{Vector{Float64}}()` and `z[] = compute(x, y)`. Outside of `f` you can then check for success of `z = f(x, y)` via `isdefined(z, :x)` (where `:x` refers to the single field of a `RefValue`).
- Declare, but don’t initialise `z` outside of the `while` loop. Raise an error if it has not been defined when you want to return it. You can do this by explicitly keeping track if `z` has been successfully computed via a `success` flag (i.e. what you’re doing now), use something like

```julia-auto
@isdefined(z) && return z
error("Fail!")

```

or just use the `UndefVarError` as a sign that the computation failed.

The first option (when done properly) should be the most performant, but also the most opaque. I.e. when debugging it might not always be clear that `Float64[]` is problematic, while `#undef` and especially an error clearly are.
