Why does Livebook require `consolidate_protocols: false`

Howdy! I’ve been using LiveBook to use as a playground/teaching tool for a small app I’m developing.

I started running into an issue where, when using LiveBook, I would get a “Jason Encoder not implemented” error for a struct that is in my project, even though I had @derive Jason.Encoder right on top of the defstruct macro in the struct’s module.

The only thing I could do to fix the error was to add consolidate_protocols: false in the Mix.install function that I run as part of my LiveBook initialization block.

The offending struct was not defined in LiveBook–it was defined in the project I’m adding to Livebook as a dependency.

I have never fully groked what “protocol consolidation” is (and I wasn’t able to fully understand the docs), but I had sort of a nebulous understanding that consolidate_protocols: false was required when structs were defined dynamically during runtime.

However, in this case that’s not true–my offending struct was defined in my project, so it seems like it’s something to do with LiveBook?

So two questions:

  1. Is this something LiveBook specific? And if so, what?
  2. Any tips for understanding what consolidate_protocols: false actually does?

FWIW, this is what my LiveBook initialization block looks like:

my_app_root = Path.join(__DIR__, "..")

Mix.install(
  [
    {:salesbot, path: my_app_root, env: :dev}, <-- This is my app
    {:kino, "~> 0.10.0"},
    {:kino_db, "~> 0.2.1"},
    {:postgrex, "~> 0.16.3"},
    {:kino_vega_lite, "~> 0.1.7"}
  ],
  config_path: Path.join(my_app_root, "config/config.exs"),
  lockfile: Path.join(my_app_root, "mix.lock"),
  consolidate_protocols: false <-- Without this line I get an error
)

Once protocols are consolidated, you can’t define new implementations. It is not a Livebook specific concern. For example, if you run iex -S mix in your project and then proceed to define an implementation in IEx, you would have the same issue. :slight_smile:

2 Likes

Hi Jose, thanks for the reply!

The issue I’m encountering is preciesely that I’m not defining a new implementation in my livebook–the implementation is defined in the app that I’m working on (and installing into the livebook in the “notebook dependencies and setup” block).

So that app gets compiled when the livebook is connected, but I still get a Jason Encoder not implemented unless I add consolidate_protocols: false for some reason?

1 Like

Hey @elbasti, does the error happen when you just call Jason.encode, or is there something more specific you do in the notebook?