# Nonsensical error in elm-language-server

**URL:** <https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354>\
**Category:** Learn\
**Created:** [September 26, 2023, 12:14pm UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354 "2023-09-26T12:14:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![peacememories](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/peacememories/32/539_2.png) [@peacememories](https://discourse.elm-lang.org/u/peacememories)\
**Post date:** [September 26, 2023, 12:14pm UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/1 "2023-09-26T12:14:25Z")

</div>

I’ve run into something I hadn’t experienced at all while using elm so far - a completely wrong error report.  
The code in question is this:

```elm
-- ...

import Json.Decode as JD
import Json.Decode.Extra as JD
import Json.Decode.Pipeline as JD

type alias ProductId =
    Int

type alias LabelNumber =
    String

type ProductType
    = MiG
    | Std100
    | Std100PPE
    | Std100SA
    | Std100Recycling
    | Ecopass
    | Step
    | Leather
    | OrganicCotton
    | OrganicCottonBlended

type alias Product =
    { productId : ProductId
    , labelNumber : LabelNumber
    , description : String
    , state : ProductState
    , productType : ProductType
    }

type ProductState
    = Fixed { expiresOn : Time.Posix }
    | Valid { expiresOn : Time.Posix }
    | Expired { expiredOn : Time.Posix }

productDecoder : JD.Decoder Product
productDecoder =
    JD.succeed Product
        |> JD.required "pk" JD.int
        |> JD.required "label_number" JD.string
        |> JD.required "description" JD.string
        |> JD.custom productStateDecoder
        |> JD.required "product" productTypeDecoder

printableProductDecoder : JD.Decoder Product
printableProductDecoder =
    productDecoder
        |> JD.andThen
            (\product ->
                case product.state of
                    Valid _ ->
                        JD.succeed product

                    Fixed _ ->
                        JD.succeed product

                    Expired _ ->
                        JD.fail ("Expired product " ++ product.labelNumber ++ " cannot be printed.")
            )

productStateDecoder : JD.Decoder ProductState
productStateDecoder =
    JD.field "product_state" JD.string
        |> JD.andThen
            (\productState ->
                case productState of
                    "FIXED" ->
                        JD.succeed (\expiresOn -> { expiresOn = expiresOn })
                            |> JD.required "expires_on" JD.datetime
                            |> JD.map Fixed

                    "VALID" ->
                        JD.succeed (\expiresOn -> { expiresOn = expiresOn })
                            |> JD.required "expires_on" JD.datetime
                            |> JD.map Valid

                    "EXPIRED" ->
                        JD.succeed (\expiredOn -> { expiredOn = expiredOn })
                            |> JD.required "expires_on" JD.datetime
                            |> JD.map Expired

                    _ ->
                        JD.fail ("Unrecognized product state: " ++ productState)
            )

productTypeDecoder : JD.Decoder ProductType
productTypeDecoder =
    JD.string
        |> JD.andThen
            (\productType ->
                case productType of
                    "MIG" ->
                        JD.succeed MiG

                    "OTS100" ->
                        JD.succeed Std100

                    "OTS100_PPE" ->
                        JD.succeed Std100PPE

                    "OTS100_SA" ->
                        JD.succeed Std100SA

                    "OTS100_RECYCLING" ->
                        JD.succeed Std100Recycling

                    "ECOPASSPORT" ->
                        JD.succeed Ecopass

                    "STEP" ->
                        JD.succeed Step

                    "LEATHER" ->
                        JD.succeed Leather

                    "ORGANIC_COTTON_BLENDED" ->
                        JD.succeed OrganicCottonBlended

                    "ORGANIC_COTTON" ->
                        JD.succeed OrganicCotton

                    _ ->
                        JD.fail (productType ++ " is not a valid product type")
            )

-- ...

```

and the language server (tested in VSCode and Helix) complains that the `printableProductDecoder` functions is wrong:

> Type mismatch error.  
> Expected: `Decoder Product`  
> Found: `Decoder { productId : ProductId, description : String, productType : ProductType, state : ProductState }`

But as can be easily seen, the function just returns the result of the `productDecoder` function, which is not highlighted.

Also, the elm compiler itself has no problems with this code, and it’s been running in production for a year without problems.

I am running this on NixOS, without globally installed Elm and elm-language-server, in case that makes any difference, but I would not know why.

Any help is greatly appreciated 😅

---

<div class="post-metadata">

**Author:** ![peacememories](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/peacememories/32/539_2.png) [@peacememories](https://discourse.elm-lang.org/u/peacememories)\
**Post date:** [September 26, 2023, 12:17pm UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/2 "2023-09-26T12:17:52Z")

</div>

Apparently the error is **only** displayed when returning an error containing `product.labelNumber`. If I remove this and just write `JD.fail ("Expired product cannot be printed.")`, no error is reported.

Also, if I instead insert a _different_ field into the string, that field is missing from the would-be return type in the error message, instead of `labelNumber`. So it seems that some part of the language-server thinks that using the field there consumes it???

---

<div class="post-metadata">

**Author:** ![peacememories](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/peacememories/32/539_2.png) [@peacememories](https://discourse.elm-lang.org/u/peacememories)\
**Post date:** [September 26, 2023, 12:20pm UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/3 "2023-09-26T12:20:26Z")

</div>

Extracting the error branch into its own function also makes the error go away… 🤔

---

<div class="post-metadata">

**Author:** ![peacememories](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/peacememories/32/539_2.png) [@peacememories](https://discourse.elm-lang.org/u/peacememories)\
**Post date:** [September 26, 2023, 12:51pm UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/4 "2023-09-26T12:51:52Z")

</div>

This gets even weirder. If I edit the file, the error appears, if I save the file without changing anything, it disappears again. So I can do the following:

1. Type a space; the error appears
2. Save; elm-format removes the space, the error is still there
3. Save again; nothing changes, the error disappears

Or

1. Type a space; the error appears
2. Remove the space; the error is still there
3. Save; nothing changes, the error disappears

---

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/benjamin-thomas/32/3869_2.png) [@benjamin-thomas](https://discourse.elm-lang.org/u/benjamin-thomas)\
**Post date:** [September 27, 2023, 5:21am UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/5 "2023-09-27T05:21:22Z")

</div>

Could you have unknowingly introduced an unprintable character in your source code?

I would diff the actual bytes before/after the bug manifests.

I noticed that elm-format replaces the non-breaking space character with a verbose and explicit equivalent so that could explain why things work after save.

---

<div class="post-metadata">

**Author:** ![peacememories](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/peacememories/32/539_2.png) [@peacememories](https://discourse.elm-lang.org/u/peacememories)\
**Post date:** [September 27, 2023, 7:50am UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/6 "2023-09-27T07:50:36Z")

</div>

I don’t think that’s likely here. For one, the saved code passes the elm compiler. And the error reappears when I just type a space. I doubt VSCode would insert a nonbreaking space automatically into a source file. I also _can’t_ diff the versions. If I save without formatting, the error disappears, no changes needed.

---

<div class="post-metadata">

**Author:** ![edkelly303](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/edkelly303/32/1510_2.png) [@edkelly303](https://discourse.elm-lang.org/u/edkelly303)\
**Post date:** [September 27, 2023, 9:59am UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/7 "2023-09-27T09:59:00Z")

</div>

I’m not sure how often the Elm Language Server maintainers are active on this forum. Maybe it would be a good idea to open an issue on [Issues · elm-tooling/elm-language-server · GitHub](https://github.com/elm-tooling/elm-language-server/issues) (if you haven’t done so already)?

---

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/benjamin-thomas/32/3869_2.png) [@benjamin-thomas](https://discourse.elm-lang.org/u/benjamin-thomas)\
**Post date:** [September 27, 2023, 11:37am UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/8 "2023-09-27T11:37:07Z")

</div>

I implied the inverse. You could have some unknown unprintable character in your source, you save and it gets removed.

It’s just speculation and an idea of course, you just need to inspect the bytes to see it it holds

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [October 7, 2023, 11:37am UTC](https://discourse.elm-lang.org/t/nonsensical-error-in-elm-language-server/9354/9 "2023-10-07T11:37:20Z")

</div>

Closed on October 7, 2023, 11:37am UTC

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
