The issue you're seeing is simply that you reused the `%*` identifier for your custom `JsonNode` converter. It confuses the compiler. `%*` is an `untyped` macro in the JSON module, which applies `%` to every field essentially.
So for your own JSON converter procs for a type, you'll want to use `%` as well. A working example: import std/json type Planet* = ref object name*: string pos*: tuple[x: float, y: float] proc `%`(planet: Planet) : JsonNode = result = %* { "name": planet.name, "pos": [ planet.pos.x, planet.pos.y ] } let p = Planet(name: "Earth", pos: (x: 149.6e9, y: 0.0)) echo pretty(% p) Run