title: Encountering errors when trying to write either a Circe encoder or decoder for ADT
body: <p>I'm trying to write some code based on <a href="https://circe.github.io/circe/codecs/adt.html" rel="nofollow noreferrer">Circe's documentation</a>, however, trying to compile both my encoder and decoder results in an error.</p>
  
  <p>If you would like to take a look at the entire project, you can do so on github (<a href="https://github.com/TomPoczos/scalpaca/blob/master/src/main/scala/model/account.scala" rel="nofollow noreferrer">link to the file I have issues with</a>)</p>
  
  <p><strong>The Decoder</strong></p>
  
  <p>Trying to compile the below code:</p>
  
  <pre><code>package model
  
  import java.time.LocalDateTime
  
  import cats.effect.IO
  import cats.syntax.functor._
  import io.circe.generic.auto._
  import io.circe.syntax._
  import io.circe.{Decoder, Encoder}
  import org.http4s.EntityDecoder
  import org.http4s.circe.jsonOf
  
  package object account {
  
    sealed trait AccountStatus
    case object Onboarding       extends AccountStatus
    case object SubmissionFailed extends AccountStatus
    case object Submitted        extends AccountStatus
    case object AccountUpdated   extends AccountStatus
    case object ApprovalPending  extends AccountStatus
    case object Active           extends AccountStatus
    case object Rejected         extends AccountStatus
  
    object AccountStatus {
  
      implicit val accountStatusEncoder: Encoder[AccountStatus] = Encoder.instance {
        case onboarding@Onboarding =&gt; onboarding.asJson
        case submissionFailed@SubmissionFailed =&gt; submissionFailed.asJson
        case submitted@Submitted =&gt; submitted.asJson
        case accountUpdated@AccountUpdated =&gt; accountUpdated.asJson
        case approvalPending@ApprovalPending =&gt; approvalPending.asJson
        case active@Active =&gt; active.asJson
        case rejected@Rejected =&gt; rejected.asJson
      }
  
      implicit val accountStatusDecoder: Decoder[AccountStatus] =
        List[Decoder[AccountStatus]](
          Decoder[Onboarding].widen,
          Decoder[SubmissionFailed].widen,
          Decoder[Submitted].widen,
          Decoder[AccountUpdated].widen,
          Decoder[ApprovalPending].widen,
          Decoder[Active].widen,
          Decoder[Rejected].widen
        ).reduceLeft(_ or _)
  
      implicit val AccountStatusEntityDecoder = jsonOf[IO, AccountStatus]
  
    }
  
  
    case class Account(
                        id: String,
                        status: AccountStatus,
                        currency: String,
                        buyingPower: Double,
                        cash: Double,
                        cashWithdrawable: Double,
                        portfolioValue: Double,
                        patternDayTrader: Boolean,
                        tradingBlocked: Boolean,
                        transfersBlocked: Boolean,
                        accountBlocked: Boolean,
                        createdAt: LocalDateTime
                      )
  
    object Account {
      implicit val AccountDecoder: EntityDecoder[IO, Account] = jsonOf[IO, Account]
    }
  </code></pre>
  
  <p>}</p>
  
  <p>results in the following errors:</p>
  
  <pre><code>[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:38:19: not found: type Onboarding
  [error]           Decoder[Onboarding].widen,
  [error]                   ^
  [error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:39:19: not found: type SubmissionFailed
  [error]           Decoder[SubmissionFailed].widen,
  [error]                   ^
  [error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:40:19: not found: type Submitted
  [error]           Decoder[Submitted].widen,
  [error]                   ^
  [error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:41:19: not found: type AccountUpdated
  [error]           Decoder[AccountUpdated].widen,
  [error]                   ^
  [error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:42:19: not found: type ApprovalPending
  [error]           Decoder[ApprovalPending].widen,
  [error]                   ^
  [error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:43:19: not found: type Active
  [error]           Decoder[Active].widen,
  [error]                   ^
  [error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:44:19: not found: type Rejected
  [error]           Decoder[Rejected].widen
  [error]                   ^
  [error] 7 errors found
  </code></pre>
  
  <p>I find this rather confusing as the types the compiler complains about are quite clearly in scope, at least as far as I can tell.</p>
  
  <p><strong>The Encoder</strong></p>
  
  <p>Removing the decoder, the AccountStatusEntityDecoder that depends on it and the AccountStatus field from account, being left with the below</p>
  
  <pre><code>package model
  
  import java.time.LocalDateTime
  
  import cats.effect.IO
  import cats.syntax.functor._
  import io.circe.generic.auto._
  import io.circe.syntax._
  import io.circe.{Decoder, Encoder}
  import org.http4s.EntityDecoder
  import org.http4s.circe.jsonOf
  
  package object account {
  
    sealed trait AccountStatus
    case object Onboarding       extends AccountStatus
    case object SubmissionFailed extends AccountStatus
    case object Submitted        extends AccountStatus
    case object AccountUpdated   extends AccountStatus
    case object ApprovalPending  extends AccountStatus
    case object Active           extends AccountStatus
    case object Rejected         extends AccountStatus
  
    object AccountStatus {
  
      implicit val accountStatusEncoder: Encoder[AccountStatus] = Encoder.instance {
        case onboarding@Onboarding =&gt; onboarding.asJson
        case submissionFailed@SubmissionFailed =&gt; submissionFailed.asJson
        case submitted@Submitted =&gt; submitted.asJson
        case accountUpdated@AccountUpdated =&gt; accountUpdated.asJson
        case approvalPending@ApprovalPending =&gt; approvalPending.asJson
        case active@Active =&gt; active.asJson
        case rejected@Rejected =&gt; rejected.asJson
      }
  
    }
  
    case class Account(
                        id: String,
                        currency: String,
                        buyingPower: Double,
                        cash: Double,
                        cashWithdrawable: Double,
                        portfolioValue: Double,
                        patternDayTrader: Boolean,
                        tradingBlocked: Boolean,
                        transfersBlocked: Boolean,
                        accountBlocked: Boolean,
                        createdAt: LocalDateTime
                      )
  
    object Account {
      implicit val AccountDecoder: EntityDecoder[IO, Account] = jsonOf[IO, Account]
    }
  
  }
  </code></pre>
  
  <p>I again get some warnings and errors:</p>
  
  <pre><code>[info] Compiling 1 Scala source to /home/tom/code/scalpaca/target/scala-2.12/classes ...
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:27:48: match may not be exhaustive.
  [warn] It would fail on the following input: Onboarding
  [warn]       case onboarding@Onboarding =&gt; onboarding.asJson
  [warn]                                                ^
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:28:66: match may not be exhaustive.
  [warn] It would fail on the following input: SubmissionFailed
  [warn]       case submissionFailed@SubmissionFailed =&gt; submissionFailed.asJson
  [warn]                                                                  ^
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:29:45: match may not be exhaustive.
  [warn] It would fail on the following input: Submitted
  [warn]       case submitted@Submitted =&gt; submitted.asJson
  [warn]                                             ^
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:30:60: match may not be exhaustive.
  [warn] It would fail on the following input: AccountUpdated
  [warn]       case accountUpdated@AccountUpdated =&gt; accountUpdated.asJson
  [warn]                                                            ^
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:31:63: match may not be exhaustive.
  [warn] It would fail on the following input: ApprovalPending
  [warn]       case approvalPending@ApprovalPending =&gt; approvalPending.asJson
  [warn]                                                               ^
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:32:36: match may not be exhaustive.
  [warn] It would fail on the following input: Active
  [warn]       case active@Active =&gt; active.asJson
  [warn]                                    ^
  [warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:33:42: match may not be exhaustive.
  [warn] It would fail on the following input: Rejected
  [warn]       case rejected@Rejected =&gt; rejected.asJson
  [warn]                                          ^
  [error] Error while emitting account.scala
  [error] assertion failed: 
  [error]   Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Onboarding$; - account.scala
  [error]      while compiling: /home/tom/code/scalpaca/src/main/scala/model/account.scala
  [error]         during phase: jvm
  [error]      library version: version 2.12.8
  [error]     compiler version: version 2.12.8
  [error]   reconstructed args: -bootclasspath /home/tom/jdk1.8.0_201/jre/lib/resources.jar:/home/tom/jdk1.8.0_201/jre/lib/rt.jar:/home/tom/jdk1.8.0_201/jre/lib/sunrsasign.jar:/home/tom/jdk1.8.0_201/jre/lib/jsse.jar:/home/tom/jdk1.8.0_201/jre/lib/jce.jar:/home/tom/jdk1.8.0_201/jre/lib/charsets.jar:/home/tom/jdk1.8.0_201/jre/lib/jfr.jar:/home/tom/jdk1.8.0_201/jre/classes:/home/tom/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.8.jar -Ypartial-unification -classpath /home/tom/code/scalpaca/target/scala-2.12/classes:/home/tom/.ivy2/cache/io.circe/circe-generic_2.12/jars/circe-generic_2.12-0.11.1.jar:/home/tom/.ivy2/cache/io.circe/circe-parser_2.12/jars/circe-parser_2.12-0.11.1.jar:/home/tom/.ivy2/cache/io.circe/circe-java8_2.12/jars/circe-java8_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.http4s/http4s-circe_2.12/jars/http4s-circe_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-dsl_2.12/jars/http4s-dsl_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-blaze-client_2.12/jars/http4s-blaze-client_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/com.chuusai/shapeless_2.12/bundles/shapeless_2.12-2.3.3.jar:/home/tom/.ivy2/cache/io.circe/circe-jawn_2.12/jars/circe-jawn_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.http4s/http4s-jawn_2.12/jars/http4s-jawn_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-client_2.12/jars/http4s-client_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-blaze-core_2.12/jars/http4s-blaze-core_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/io.circe/circe-core_2.12/jars/circe-core_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.typelevel/macro-compat_2.12/jars/macro-compat_2.12-1.1.1.jar:/home/tom/.ivy2/cache/org.typelevel/jawn-parser_2.12/jars/jawn-parser_2.12-0.14.1.jar:/home/tom/.ivy2/cache/org.http4s/jawn-fs2_2.12/jars/jawn-fs2_2.12-0.13.0.jar:/home/tom/.ivy2/cache/org.http4s/http4s-core_2.12/jars/http4s-core_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/blaze-http_2.12/jars/blaze-http_2.12-0.14.0-M11.jar:/home/tom/.ivy2/cache/io.circe/circe-numbers_2.12/jars/circe-numbers_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.spire-math/jawn-parser_2.12/jars/jawn-parser_2.12-0.13.0.jar:/home/tom/.ivy2/cache/org.http4s/parboiled_2.12/jars/parboiled_2.12-1.0.0.jar:/home/tom/.ivy2/cache/co.fs2/fs2-io_2.12/jars/fs2-io_2.12-1.0.2.jar:/home/tom/.ivy2/cache/org.eclipse.jetty.alpn/alpn-api/jars/alpn-api-1.1.3.v20160715.jar:/home/tom/.ivy2/cache/com.twitter/hpack/jars/hpack-1.0.2.jar:/home/tom/.ivy2/cache/org.http4s/blaze-core_2.12/jars/blaze-core_2.12-0.14.0-M11.jar:/home/tom/.ivy2/cache/org.log4s/log4s_2.12/jars/log4s_2.12-1.6.1.jar:/home/tom/.ivy2/cache/co.fs2/fs2-core_2.12/jars/fs2-core_2.12-1.0.2.jar:/home/tom/.ivy2/cache/org.typelevel/cats-effect_2.12/jars/cats-effect_2.12-1.1.0.jar:/home/tom/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.25.jar:/home/tom/.ivy2/cache/org.scodec/scodec-bits_2.12/jars/scodec-bits_2.12-1.1.7.jar:/home/tom/.ivy2/cache/org.typelevel/cats-core_2.12/jars/cats-core_2.12-1.5.0.jar:/home/tom/.ivy2/cache/org.typelevel/cats-kernel_2.12/jars/cats-kernel_2.12-1.5.0.jar:/home/tom/.ivy2/cache/org.typelevel/cats-macros_2.12/jars/cats-macros_2.12-1.5.0.jar:/home/tom/.ivy2/cache/org.typelevel/machinist_2.12/jars/machinist_2.12-0.6.6.jar:/home/tom/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.12.6.jar
  [error] 
  [error]   last tree to typer: TypeTree(trait Decoder)
  [error]        tree position: line 53 of /home/tom/code/scalpaca/src/main/scala/model/account.scala
  [error]             tree tpe: io.circe.Decoder
  [error]               symbol: abstract trait Decoder in package circe
  [error]    symbol definition: abstract trait Decoder extends Serializable (a ClassSymbol)
  [error]       symbol package: io.circe
  [error]        symbol owners: trait Decoder
  [error]            call site: constructor package$Account$anon$importedDecoder$macro$28$1$anon$macro$25$1 in package account
  [error] 
  [error] == Source file context for tree position ==
  [error] 
  [error]     50                     )
  [error]     51 
  [error]     52   object Account {
  [error]     53     implicit val AccountDecoder: EntityDecoder[IO, Account] = jsonOf[IO, Account]
  [error]     54   }
  [error]     55 
  [error]     56 }
  [error] Error while emitting account.scala
  [error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$SubmissionFailed$; - account.scala
  [error] Error while emitting account.scala
  [error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Submitted$; - account.scala
  [error] Error while emitting account.scala
  [error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$AccountUpdated$; - account.scala
  [error] Error while emitting account.scala
  [error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$ApprovalPending$; - account.scala
  [error] Error while emitting account.scala
  [error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Active$; - account.scala
  [error] Error while emitting account.scala
  [error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Rejected$; - account.scala
  [warn] 7 warnings found
  [error] 7 errors found
  </code></pre>
  
  <p>I can't figure out why Account is affected. <em>If I remove the AccountStatus companion object entirely my project compiles.</em></p>
  
  <p>I'd like some help getting rid of these errors, your input would still be appreciated. Thanks </p>