Type checking is failing with this example. Am I missing something or is this a bug?
get_greeting : {} -> Try(Str, _)
get_greeting = |{}| {
match 0 {
0 => Try.Ok(List.first(["hello"])?),
_ => Err(Impossible)
}
}
main! = || {
Stdout.line!(get_greeting({}).ok_or("Error!"))
}
I get the following error message:
This expression is used in an unexpected way:
┌─ test/fx/question_mark_operator_branching.roc:10:5
│
10 │ match 0 {
11 │ 0 => Try.Ok(List.first(["hello"])?),
12 │ _ => Err(Impossible)
13 │ }
It has the type:
Try(Str, [Impossible, .._others])
But the type annotation says it should have the type:
Try(Str, [ListWasEmpty])
seems like a bug, I'll look into it!
maybe an even simpler test with "if" branching is possible. I haven’t checked if it’s "match" specific or reproducible with branching in general.
it's that we don't have polarity yet (cc @Jared Ramirez, not sure if you've started on that yet!) so it's treating [ListWasEmpty] from List.first as a closed union
I can manually annotate all the builtins as open and it should fix it
and then can put them back to the current signatures after we add polarity to the type-checker
Meanwhile, I’m just going to do a double match to make the type checker happy. Now I’m getting this for my program. Not sure where to start looking at. Any suggestions?
❯ roc day02.roc
Roc crashed: e_closure: failed to resolve capture value
I have also seen the "e_closure" problem. It occured to me when i tried following:
for line in test_input.split_on("\n") {
if line.starts_with("L") {
val = I64.from_str(line.drop_prefix("L"))
dbg val
}
}
After peeking at your solution i got around that one by moving the line.drop_prefix("L") before the if. So my guess would be that there is some problem using a value in an inner scope which is already captured in an outer scope or something. Not sure how properly describe it.
can you give me a .roc file to repro?
doesn't need to be minimal, just something where I can run roc and reproduce it
yep, exactly what I was preparing
https://github.com/roc-lang/roc/issues/8547
Don’t know if Claude root cause analysis is correct, but I figured I’d leave it there for you to judge.
thanks! the original error in this thread is fixed now btw
Matthieu Pizenberg said:
Meanwhile, I’m just going to do a double match to make the type checker happy. Now I’m getting this for my program. Not sure where to start looking at. Any suggestions?
❯ roc day02.roc Roc crashed: e_closure: failed to resolve capture value
I've also been having this issue with closures, got it with this sample program:
main! = |args| {
identity = |a| a
init_try : Try(U32, [SomeError, ..others])
init_try = Err(SomeError)
final_try = match init_try {
Ok(ok) => Ok(ok)
Err(e) => Err(identity(e))
}
was_an_error = Try.is_err(final_try)
Stdout.line!("final_try is an error: ${was_an_error}")
Ok({})
}
# Error: Roc crashed: e_closure: failed to resolve capture value
I tried with Strings and numerics and without type signatures they would crash, with type signatures they can succeed. But when using a Try type this always fails, with or without a type signature or changing the error type to something like [..others] or just SomeError. I also swapped Err(SomeError) with Ok(30) and still get the closure error. Was trying to get a closure like |_| Exit(101) going.
@Edwin Santos @Matthieu Pizenberg this is fixed now!
Richard Feldman said:
it's that we don't have polarity yet (cc Jared Ramirez, not sure if you've started on that yet!) so it's treating
[ListWasEmpty]fromList.firstas a closed union
i have polarity partially implemented, but there’s still a bit of work until its ready to go
yeah no rush! modifying the types in Builtin.roc to make the tag unions expicitly open fixed it
Last updated: Dec 21 2025 at 12:15 UTC