Jason.Encoder derive not working for me. What am I doing wrong?

I have a struct I’m trying to derive called Geo.Point. I don’t own it.

require Protocol
Protocol.derive(Jason.Encoder, Geo.Point, only: [:coordinates])
%Geo.Point{} |> Jason.encode
{:error,
 %Protocol.UndefinedError{
   description: "Jason.Encoder protocol must always be explicitly implemented.\n\nIf you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:\n\n    @derive {Jason.Encoder, only: [....]}\n    defstruct ...\n\nIt is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:\n\n    @derive Jason.Encoder\n    defstruct ...\n\nFinally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:\n\n    Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])\n    Protocol.derive(Jason.Encoder, NameOfTheStruct)\n",
   protocol: Jason.Encoder,
   value: %Geo.Point{coordinates: {0, 0}, properties: %{}, srid: nil}
 }}

But I can’t even get it to work for my own structs

defmodule X do
  # I tried both with and without this line.
  @derive {Jason.Encoder, only: [:id]}
  defstruct [:id]
end
Protocol.derive(Jason.Encoder, X, only: [:id])
%X{id: 1} |> Jason.encode
{:error,
 %Protocol.UndefinedError{
   description: "Jason.Encoder protocol must always be explicitly implemented.\n\nIf you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:\n\n    @derive {Jason.Encoder, only: [....]}\n    defstruct ...\n\nIt is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:\n\n    @derive Jason.Encoder\n    defstruct ...\n\nFinally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:\n\n    Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])\n    Protocol.derive(Jason.Encoder, NameOfTheStruct)\n",
   protocol: Jason.Encoder,
   value: %X{id: 1}
 }}

I get this whether I use Protocol.derive/3 in the console, or even if I put @derive {Jason.Encoder, only: [:id]} in the struct itself.

What am I missing here?

Read the warning you get back. Protocols are to be comsolidated. Either suppress consolidation in mix.exs for this environment, or put the code into some file within the project, and get into the shell with iex -S mix.