Circe Couldn't convert raw json to case class Error: could not find Lazy implicit value of type io.circe.generic.decoding.DerivedDecoder

The reason you can't derive a decode for CustomObject is because of the labels: Object member.

In circe all decoding is driven by static types, and circe does not provide encoders or decoders for types like Object or Any, which have no useful static information.

If you change that case class to something like the following:

case class CustomObject(apiVersion: String, kind: String, metadata: Metadata, spec: Spec)

…and leave the rest of your code as is, with the import:

import io.circe.Decoder, io.circe.generic.semiauto.deriveDecoder

And define your JSON document as doc (after adding a quotation mark to the "image": "gcr.io/ynli-k8s/spark:v2.4.0, line to make it valid JSON), the following should work just fine:

scala> io.circe.jawn.decode[CustomObject](doc)
res0: Either[io.circe.Error,CustomObject] = Right(CustomObject(sparkoperator.k8s.io/v1alpha1,SparkApplication,Metadata(2019-01-11T15:58:45Z,1,uid,268972,spark-example,default,/apis/sparkoperator.k8s.io/v1alpha1/namespaces/default/sparkapplications/spark-example),Spec(cluster,gcr.io/ynli-k8s/spark:v2.4.0,Always,http://localhost:8089/spark_k8s_airflow.jar,org.apache.spark.examples.SparkExample,Deps(),Driver(0.1,1000m,1024m,default,Labels(2.4.0)),Executor(1.0,1.0,1024m,Labels(2.4.0)),Subresources(Status()))))

Despite what one of the other answers says, circe can definitely derive encoders and decoders for case classes with no members—that's definitely not the problem here.

As a side note, I wish it were possible to have better error messages than this:

Error: could not find Lazy implicit value of type io.circe.generic.decoding.DerivedDecoder[dataModel.CustomObject

But given the way circe-generic has to use Shapeless's Lazy right now, this is the best we can get. You can try circe-derivation for a mostly drop-in alternative for circe-generic's semi-automatic derivation that has better error messages (and some other advantages), or you can use a compiler plugin like splain that's specifically designed to give better error messages even in the presence of things like shapeless.Lazy.

As one final note, you can clean up your semi-automatic definitions a bit by letting the type parameter on deriveDecoder be inferred:

implicit val customObjectLabelsDecoder: Decoder[Labels] = deriveDecoder

This is entirely a matter of taste, but I find it a little less noisy to read.