Stream: ideas

Topic: Error format


view this post on Zulip Aurélien Geron (Aug 05 2026 at 23:00):

image.png

The current "boxed" format for errors looks cool, but imho it's not very practical:

I propose going for a simpler format, such as:

# ❌ FAIL ────────────────────────────────────────────
# /mnt/exercism-iteration/reverse-string-test.roc:60:1
# ────────────────────────────────────────────────────
expect {
    result = reverse("ผู้เขียนโปรแกรม")
    result == "มรกแรปโนยขีเผู้"
}

This output can be directly copy/pasted to a Roc file, including the header (thanks to the #). It also takes up 30% less horizontal and vertical space (in this example), resizing the window will work as expected, and I find it easier to parse visually.

view this post on Zulip Richard Feldman (Aug 05 2026 at 23:39):

that's cool! :smiley:

view this post on Zulip Aurélien Geron (Aug 06 2026 at 00:32):

Glad you like the idea! :blush:
Another benefit is that you get Roc syntax highlighting if you copy/paste the error to a GitHub issue. :art:

view this post on Zulip Richard Feldman (Aug 06 2026 at 00:35):

I wonder what that same design would look like in other error messages

view this post on Zulip Aurélien Geron (Aug 06 2026 at 00:37):

Agreed, I'll look into that

view this post on Zulip Aurélien Geron (Aug 06 2026 at 01:30):

Here's a proposal for each error/warning format.

1. Failed Unit Tests (roc test / FAIL)

Current (Box Format)

┌──────┐
│ FAIL ├─  ───────────────────────────────────────────────────────────────────┐
└┬─────┘                                                                      │
 │                                                                            │
 │  expect {                                                                  │
 │      result = reverse("ผู้เขียนโปรแกรม")                                   │
 │      result == "มรกแรปโนยขีเผู้"                                           │
 │  }                                                                         │
 │                                                                            │
 └────────────────────── /mnt/exercism-iteration/reverse-string-test.roc:60:1 ┘

Proposed (Comment Format)

# ❌ FAIL ────────────────────────────────────────────
# /mnt/exercism-iteration/reverse-string-test.roc:60:1
# ────────────────────────────────────────────────────
expect {
    result = reverse("ผู้เขียนโปรแกรม")
    result == "มรกแรปโนยขีเผู้"
}

2. Single-Line Source Error with Underline (e.g., TYPE MISMATCH, SYNTAX PROBLEM, NAME NOT IN SCOPE)

Current (Box Format)

┌───────────────┐
│ TYPE MISMATCH ├─ This string literal is being used where a non-string ──────┐
└┬──────────────┘  type is needed.                                            │
 │                                                                            │
 │      "hello world",                                                        │
 │      ‾‾‾‾‾‾‾‾‾‾‾‾‾                                                         │
 └──────────────────────────────────────── can_list_multiline_mismatch.md:3:7 ┘

 The type was determined to be:
     Dec

Proposed (Comment Format)

# ❌ TYPE MISMATCH ───────────────────────────────────
# can_list_multiline_mismatch.md:3:7
# This string literal is being used where a non-string type is needed.
# The type was determined to be:
#    Dec
# ────────────────────────────────────────────────────
       "hello world",
       ^^^^^^^^^^^^^

3. Multi-Region Error with Multiple Underlines (e.g., Mismatched if/else Branches, Function Arity)

Current (Box Format)

┌───────────────┐
│ TYPE MISMATCH ├─ This `if` condition has different return types in branches. ┐
└┬──────────────┘                                                              │
 │                                                                             │
 │  if cond                                                                    │
 │      "hello"                                                                │
 │      ‾‾‾‾‾‾‾                                                                │
 │  else                                                                       │
 │      123                                                                    │
 │      ───                                                                    │
 └─────────────────────────────────────────────── examples/branches.roc:10:5 ──┘

Proposed (Comment Format)

# ❌ TYPE MISMATCH ────────────────────────────────────
# examples/branches.roc:10:5
# This `if` condition has different return types in branches.
# ─────────────────────────────────────────────────────
if cond
    "hello"
    ^^^^^^^
else
    123
    ^^^

4. Error with Secondary / Reference Location Snippet (e.g., DUPLICATE DEFINITION, TYPE REDECLARED)

Current (Box Format)

┌──────────────────────┐
│ DUPLICATE DEFINITION ├─ The name `x` is being redeclared here. ─────────────┐
└┬─────────────────────┘                                                      │
 │                                                                            │
 │  x = 20  # Should shadow top-level x                                       │
 │  ‾                                                                         │
 └────────────────────────────────────────────────── can_basic_scoping.md:7:5 ┘

 In this scope, `x` was already defined here:
   ┌───────────────────────────────────────────────────────┐
 2 │  x = 5                                                │
   │  ‾                                                    │
   └───────────────────────────── can_basic_scoping.md:2:1 ┘

Proposed (Comment Format)

# ❌ DUPLICATE DEFINITION ─────────────────────────────
# can_basic_scoping.md:7:5
# The name `x` is being redeclared here.
# ─────────────────────────────────────────────────────
x = 20  # Should shadow top-level x
^

# ℹ️ DETAILS ────────────────────
# can_basic_scoping.md:2:1
# In this scope, `x` was already defined here:
# ───────────────────────────────
x = 5
^

5. Warnings (e.g., UNUSED VARIABLE, UNUSED IMPORT, TYPE SHADOWED)

Current (Box Format)

┌─────────────────┐
│ UNUSED VARIABLE ├─ Variable `unused_val` is defined but never used. ────┐
└┬────────────────┘                                                       │
 │                                                                        │
 │  unused_val = 42                                                       │
 │  ‾‾‾‾‾‾‾‾‾‾                                                            │
 └───────────────────────────────────────────────────────── main.roc:12:5 ┘

Proposed (Comment Format)

# ⚠️ UNUSED VARIABLE ──────────────────────────────────
# main.roc:12:5
# Variable `unused_val` is defined but never used.
# ─────────────────────────────────────────────────────
unused_val = 42
^^^^^^^^^^

6. Global / Fallback Error Reports (No Source Region)

Current (Box Format)

FILE NOT FOUND

I could not find the file `missing_module.roc`.

Proposed (Comment Format)

# ❌ FILE NOT FOUND ───────────────────────────────────
# I could not find the file `missing_module.roc`.
# ─────────────────────────────────────────────────────

view this post on Zulip Aurélien Geron (Aug 06 2026 at 02:19):

After more thought, I'm not sure we should make the error headers Roc comments: it's got its upsides, but it might make it harder to parse the errors, especially if the user's code contains comments. Perhaps the error headers should remain boxes, but more concise. However, the user's code should remain without boxes, for example:

┌─ ❌ DUPLICATE DEFINITION
│ The name `x` is being redeclared here.
└─ can_basic_scoping.md:7:5
x = 20  # Should shadow top-level x
^

┌─ ℹ️ DETAILS
│ In this scope, `x` was already defined here:
└─ can_basic_scoping.md:2:1
x = 5
^

I removed the right part of the box for many of the same reasons as for the code, e.g., resizing a full box would be ugly.

view this post on Zulip Jared Ramirez (Aug 06 2026 at 02:23):

+1 for not having headers as comments

view this post on Zulip Jared Ramirez (Aug 06 2026 at 02:24):

i like elm-style, but mb not indented for easy copy/paste

view this post on Zulip Aurélien Geron (Aug 06 2026 at 02:26):

Something like this?
image.png

view this post on Zulip Jared Ramirez (Aug 06 2026 at 02:31):

yeah! i always found the ——- separators clear to distinguish between errors, when scanning, and felt the sequence of:

title, 1-like summary, code, types, hints

as telling a clear story within a single error

view this post on Zulip Aurélien Geron (Aug 06 2026 at 02:36):

Yes, it looks simple and clear, indeed. Would you get rid of the line number and indentation for the code? I like that Roc's error messages have a link containing the file name, line number, and horizontal position, so I can click on the link and arrive straight at the right location in my editor.

view this post on Zulip Jared Ramirez (Aug 06 2026 at 02:39):

yeah, maybe we keep the line/col in the title line, eg TITLE——-—-file.roc:6:7 ?

view this post on Zulip Aurélien Geron (Aug 06 2026 at 03:50):

Something like this?

image.png

view this post on Zulip Aurélien Geron (Aug 06 2026 at 05:57):

Actually the light gray is hard to read, it looks nicer in white, imo:

image.png

view this post on Zulip Aurélien Geron (Aug 06 2026 at 05:59):

And here's an error:

image.png

view this post on Zulip Norbert Hajagos (Aug 06 2026 at 07:58):

I like the last examples. I'd just modify the hints so that the DETAILS sections doesn't have a full line which makes me think it's its own separate diagnostic item, not that it belongs to the one above it.
I get that you now have to put the file link somewhere else, but imho its not worth it for the consistency. Either we put the link somewhere else for hints or we put it elsewhere for every diagnostic item.

view this post on Zulip Jasper Woudenberg (Aug 06 2026 at 08:58):

Love these improvements! +1 to Norbert's suggestion of only using the horizontal lines between different errors/diagonostics so those are super-easy to distinguish.

And +1 to the idea of not using the light grey, for better contrast.

view this post on Zulip Aurélien Geron (Aug 06 2026 at 08:59):

Cool, I'm on it.
I've submitted PR #10643 but I'll update it in a few minutes to avoid the separate DETAILS section.

view this post on Zulip Aurélien Geron (Aug 06 2026 at 09:04):

How about this?

image.png

view this post on Zulip Lukas Juhrich (Aug 06 2026 at 12:01):

I like the visual cleanup!

I'm not sure though using emojis is a good idea; they tend to look vastly different depending on OS/Font, and judging from the screenshots I'd say they take up too much visual attention.
What about lightweight unicode symbols like , or 🛈, maybe framing it like [] to regain lost visual weight, and a Σ to prefix the stats line? To give some ideas for what it could look like (ghostty, don't know the font):

image.png

view this post on Zulip Jasper Woudenberg (Aug 06 2026 at 12:50):

Looks beautiful!

I know this goes against the copyability goal, but I do think putting the line number in front of the error line like Elm does helps me visually, because it makes the error look more like a snippet from my editor.

In addition I think the column number doesn't add much for me given there's also the highlighted snippet of code in the error, which I think communicates the location of the error on the line better. I do think the column number makes a ton of sense in compiler output intended for programmatic reading by tools though.

view this post on Zulip Matthieu Pizenberg (Aug 06 2026 at 13:07):

BTW ^^ (my firefox on macos)
image.png

view this post on Zulip Jared Ramirez (Aug 06 2026 at 13:15):

yeah, i guess what are the concrete use-cases for wanting to copy/paste the code from an error snippet?

i also agree the line numbers in the code snippet are visually orienting & imo look nice

view this post on Zulip Lukas Juhrich (Aug 06 2026 at 15:25):

Matthieu Pizenberg said:

BTW ^^ (my firefox on macos)
image.png

Ah, similar for me on mobile :sweat_smile:

view this post on Zulip Aurélien Geron (Aug 06 2026 at 20:09):

Great points, thanks. I love the ghostty style without emojis, it looks beautiful with the text colors too. One detail is that I prefer to make the dashes go to the end of the line, as in Elm (but with a maximum width of 120 characters).

I played around with the new format yesterday, and I realized that the main benefit of dropping the boxes is getting rid of the pipes on the right, because I frequently resize my window and the pipes end up on the next line when shrinking the width. This happens as well with the dashes in the new design, but much less often because of the 120 char limit, and it's less annoying because it mostly affects the dashed lines. Not having the right pipes anymore feels so much better!

After more thought, the copy/paste benefit is secondary. I personally quite like the current clean look without the line numbers, but if most people prefer showing line numbers, I'm happy to add them.

I like having the horizontal position in the link because I can Cmd-click and arrive straight at the right position. It's useful particularly for long lines and I don't think it hurts much visually, do you?

I'll make these changes today.

view this post on Zulip Aurélien Geron (Aug 06 2026 at 20:15):

/poll Show line numbers on the left of the code?
Yes
No
I like both

view this post on Zulip Aurélien Geron (Aug 06 2026 at 20:18):

/poll File location format?
Foo.roc:51:64
Foo.roc:51
Foo.roc

view this post on Zulip Aurélien Geron (Aug 06 2026 at 20:19):

I included the Foo.roc option for completeness, but I really don't recommend it because it doesn't let the user click the link to go to the right line.

view this post on Zulip Aurélien Geron (Aug 07 2026 at 04:22):

I updated PR #10643. I went with the ghostty style, without line numbers for now. Here's what it looks like:

image.png

image.png

I tried the light purple color for the last line, but the mix of colors was too much:

image.png

This is why I went with white instead.

view this post on Zulip Anton (Aug 07 2026 at 13:02):

I like it :)

view this post on Zulip Richard Feldman (Aug 07 2026 at 14:15):

here's a related option: use for errors and ⚠︎ for warnings without brackets around them

mockup

view this post on Zulip Richard Feldman (Aug 07 2026 at 14:31):

there's also for warnings, which is not semantically a warning, but it's more legible because it's bigger

bigger triangle

view this post on Zulip Aurélien Geron (Aug 07 2026 at 19:58):

Looks great!
I see you made the header text white rather than colored, including the file name. It might indeed be easier to read this way. And you replaced dashes with horizontal lines. I'm fine with these changes but I think the horizontal white lines might stand out a bit too much, wdyt?

view this post on Zulip Richard Feldman (Aug 07 2026 at 22:52):

the color wasn't intentional, just didn't bother :smile:

view this post on Zulip Richard Feldman (Aug 07 2026 at 22:53):

I like the horizontal solid lines tho

view this post on Zulip Bryce Miller (Aug 07 2026 at 23:06):

I think I like the solid lines too!

view this post on Zulip Aurélien Geron (Aug 07 2026 at 23:23):

Sounds good. However, I think ⟁ is problematic in two ways:

  1. it's from the Miscellaneous Mathematical Symbols-A block, and according to Gemini it's unlikely to display correctly on many mobile devices and standard web fonts.
  2. it's wider than a normal character, and depending on the UI, it ends up being only half displayed, or it messes with the alignment.
    For example, in VSCode:
    image.png
    In iTerm2:
    image.png

view this post on Zulip Aurélien Geron (Aug 07 2026 at 23:39):

Voting time! For errors:

image.png

view this post on Zulip Aurélien Geron (Aug 07 2026 at 23:39):

/poll
Option 1:
Option 2
Option 3
Option 4

view this post on Zulip Aurélien Geron (Aug 07 2026 at 23:47):

For warnings:

image.png

view this post on Zulip Aurélien Geron (Aug 07 2026 at 23:48):

/poll Which option do you prefer?
Option 1: Δ
Option 2: △
Option 3: ⚠
Option 4: !

view this post on Zulip Aurélien Geron (Aug 08 2026 at 00:05):

And lastly, for the final summary:

image.png

view this post on Zulip Aurélien Geron (Aug 08 2026 at 00:05):

/poll Which option do you prefer?
Option 1: ∴
Option 2: Σ
Option 3: ≡
Option 4: »

view this post on Zulip Aurélien Geron (Aug 08 2026 at 00:20):

I updated the PR with my preferences (I'll update if the poll results are different). Here's what the full output looks like now:

image.png

view this post on Zulip Richard Feldman (Aug 08 2026 at 01:11):

I kinda like for the summary just not having an icon or "found" - so just like "0 errors and 2 warnings" with the line and the filename

view this post on Zulip Richard Feldman (Aug 08 2026 at 01:11):

I intentionally chose the wording of that so that the very first part of the message is the thing you care about most: the number of errors

view this post on Zulip Richard Feldman (Aug 08 2026 at 01:11):

so I'd like to avoid having things before that...I think the line is fine though

view this post on Zulip Aurélien Geron (Aug 08 2026 at 01:25):

Done, I updated the PR.
image.png

view this post on Zulip Aurélien Geron (Aug 08 2026 at 02:01):

Do you prefer an extra empty line at the end of each section?

image.png

view this post on Zulip Jared Ramirez (Aug 08 2026 at 03:53):

i like without the extra line!

view this post on Zulip Aurélien Geron (Aug 10 2026 at 03:02):

I replaced with ! and updated the PR. I quite like the format now:

image.png

If you're onboard with this change, could someone kindly review the PR (and hopefully merge it) when you have a minute? :folded_hands:

view this post on Zulip Richard Feldman (Aug 10 2026 at 03:09):

I'm not a fan of any of the warning icon options :thinking:

view this post on Zulip Richard Feldman (Aug 10 2026 at 03:10):

which is a shame

view this post on Zulip Aurélien Geron (Aug 10 2026 at 03:12):

Any suggestions?

view this post on Zulip Aurélien Geron (Aug 10 2026 at 03:24):

A few more options:

image.png

view this post on Zulip Richard Feldman (Aug 10 2026 at 03:51):

to my surprise, I kinda dig the solid circle

view this post on Zulip Aurélien Geron (Aug 10 2026 at 03:52):

Yeah, I was thinking the same! I'll update the PR.

view this post on Zulip Richard Feldman (Aug 10 2026 at 03:56):

I'm trying to guess why it works for me; I think maybe it's that:

view this post on Zulip Richard Feldman (Aug 10 2026 at 03:59):

thanks for going through all those options @Aurélien Geron! :smiley:

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:23):

I just pushed the updated PR.

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:24):

Did we ever need Info severity reports?

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:25):

I wonder why I added that in the original reporting module... I must have got the idea from somewhere

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:25):

Ah good point, we don't anymore. I'm removing this code.

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:27):

I'm seeing file paths like this, it doesnt quite look right

(tuple_bool.md:1:38):
(tuple_bool.md:1:45):

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:29):

I believe that's for the secondary locations, such as in duplicate definition warnings:

image.png

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:30):

How do we calculate the number of dashes to add in the header line? This is what the snapshots look like now.
image.png

I remember we had the indentation which I think the markdown files we recognised as code blocks. I'm not saying we should change our error format to suite the snapshot file markdown format, just noticed.

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:32):

Regarding the secondary locations, perhaps you might prefer it without "here" and without parentheses?

image.png

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:33):

Regarding the snapshots, I guess we should put the whole thing in a code block so it is rendered in the browser using a monospaced font.

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:34):

Regarding the weird width, I wonder whether that's because the horizontal width character is wider than other characters when you're not using a fixed-width font?

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:34):

Oh that's what you just said :sweat_smile:

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:35):

This is the terminal formatting right, I guess we haven't looked at the markdown, html or other renderers from our reporting module?

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:37):

Ah no, I didn't realize they had their own renderers. :face_with_open_eyes_and_hand_over_mouth:

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:38):

LSP too, I forgot that. I'm not sure they need to all be in scope for this PR.

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:40):

Honestly thinking about this more we should probably have the snapshots render a canonicalized debug format for the errors, possibly even an S-expression.

And then have a separate snapshot format just for errors where we render all of the variations (CLI, HTML, LSP, Markdown)

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:41):

The errors in the vast majority of the snapshots would be a semantic level that doesn't change with presentation formats then.

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:42):

Yes, that would be great.

view this post on Zulip Aurélien Geron (Aug 10 2026 at 04:42):

Ok, probably in another PR, then? I'll update the PR to replace here (foo.roc:1:2): with in foo.roc:1.2:.

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:42):

When we make changes to the reporting render formats that would be isolated to the error specific snapshot types

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:42):

Yeah this is probably getting too broad to stack into this one.

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:45):

I'll make an issue for the snapshot ideas

view this post on Zulip Luke Boswell (Aug 10 2026 at 04:48):

https://github.com/roc-lang/roc/issues/10720

view this post on Zulip Aurélien Geron (Aug 11 2026 at 07:46):

Ok, I've asked an agent (Sol 5.6) to review the PR and fix a few issues I had noticed, in particular the way the secondary locations were handled. I read through the changes, and I think it looks good now. Btw, I tweaked one thing which I think makes the output even nicer: the ^^^^ for warnings are yellow now. So it looks like this:

image.png


Last updated: Aug 12 2026 at 12:35 UTC