Started getting a Protocol.UndefinedError for %Postgrex.Query{} in Ecto

I booted my application today and started getting the following error. This is weird because it was running fine the last time I booted. A simple query iex> Storage.Repo.all(Storage.Schema.User) yields the below Protocol error.

Anyone seen this before? I can’t make sense of the error.

** (Protocol.UndefinedError) protocol String.Chars not implemented for %Postgrex.Query{columns: ["id", "email", "phone", "password_hash", "status", "inserted_at", "updated_at"], name: "ecto_1938", param_formats: [], param_oids: [], param_types: [], ref: #Reference<0.0.1.1248>, result_formats: [:binary, :binary, :binary, :binary, :binary, :binary, :binary], result_oids: [23, 1043, 1043, 1043, 23, 1114, 1114], result_types: [Postgrex.Extensions.Int4, Postgrex.Extensions.Raw, Postgrex.Extensions.Raw, Postgrex.Extensions.Raw, Postgrex.Extensions.Int4, Ecto.Adapters.Postgres.Timestamp, Ecto.Adapters.Postgres.Timestamp], statement: "SELECT u0.\"id\", u0.\"email\", u0.\"phone\", u0.\"password_hash\", u0.\"status\", u0.\"inserted_at\", u0.\"updated_at\" FROM \"user\" AS u0", types: {Ecto.Adapters.Postgres.TypeModule, 176178}}
           (elixir) lib/string/chars.ex:3: String.Chars.impl_for!/1
           (elixir) lib/string/chars.ex:17: String.Chars.to_string/1
             (ecto) lib/ecto/adapters/sql.ex:653: Ecto.Adapters.SQL.log/4
    (db_connection) lib/db_connection.ex:1177: DBConnection.log/6
             (ecto) lib/ecto/adapters/postgres/connection.ex:80: Ecto.Adapters.Postgres.Connection.prepare_execute/5
             (ecto) lib/ecto/adapters/sql.ex:243: Ecto.Adapters.SQL.sql_call/6
             (ecto) lib/ecto/adapters/sql.ex:431: Ecto.Adapters.SQL.execute_and_cache/7
             (ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5

Updating postgrex from 0.13.0 to 0.13.2 solved my issue. Don’t know why tho :confused:

Are you using an umbrella project by chance?

I’ve experienced similar bug several times already when switching between umbrella root, and one of the applications and compiling from different places - it seems the protocol consolidation pass gets confused. Recompiling the project fixes the issue (and upgrading a dep, will force a recompile). Unfortunately, I wasn’t able to reproduce this reliably (and I spent a few hours trying to).

Yes, actually. I do the very same thing - switching between development work in the shell from the application with the Ecto dependency and the root umbrella project.

So the Postgrex update wasn’t a solve but a coincidence :thinking:

I didn’t see this as an open issue in the Postgrex or Ecto projects.

If it is a protocol consolidation issue then it should be in the Elixir project I’d think, but a reproducible example would be best… :-/

Yeah, it’s an issue with Elixir itself. I don’t think there’s anything specific to ecto or postgrex.

I’ll open an issue on Elixir since it seems it’s a real one and I’m not going crazy :grimacing:.

2 Likes

I also came across this issue today and was happy to find the solution. I have no idea how I could reproduce it, though.

Just came across this problem again today. Deleting the _build directory and recompiling fixed it.

1 Like

For those running into this issue, it looks like it’s been solved in Elixir 1.5. I am still running 1.4 and got it again.

https://github.com/elixir-lang/elixir/issues/5987

3 Likes

I’ve got this problem again in Elixir 1.6

Well the original issue was resolved so this might be something new…

Do you have a project that reproduces it? What is an example iex session demonstrating it? Etc… :slight_smile:

It was in a phoenix server using ecto. If I ran iex -S mix from one of the apps in the umbrella there was no problem inserting to the database. If I ran phx.server and didn’t call the ecto code there was still no problem. But then from the phoenix server if I tried to make an insert to the database (which was the first thing I tried implementing with ecto) it would give the following error:

[error] #PID<0.456.0> running WebApi.Endpoint terminated
Server: 0.0.0.0:4000 (http)
Request: POST /graphiql
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol String.Chars not implemented for %Postgrex.Query{columns: ["id"], name: "", param_formats: [:binary, :binary, :binary, :binary, :binary], param_oids: [16, 1043, 1043, 1043, 1043], param_types: [Postgrex.Extensions.Bool, Postgrex.Extensions.Raw, Postgrex.Extensions.Raw, Postgrex.Extensions.Raw, Postgrex.Extensions.Raw], ref: #Reference<0.0.2.979>, result_formats: [:binary], result_oids: [20], result_types: [Postgrex.Extensions.Int8], statement: ["INSERT INTO ", [34, "users", 34], [], [32, 40, [[[[[[], [34, "confirmed", 34], 44], [34, "email", 34], 44], [34, "password", 34], 44], [34, "salt", 34], 44], 34, "username", 34], ") VALUES ", [], 40, [[[[[[], [36 | "1"], 44], [36 | "2"], 44], [36 | "3"], 44], [36 | "4"], 44], 36 | "5"], 41], [], " RETURNING ", [], 34, "id", 34], types: {Ecto.Adapters.Postgres.TypeModule, 626738}}. This protocol is implemented for: Atom, BitString, Date, DateTime, Float, Integer, List, NaiveDateTime, Time, URI, Version, Version.Requirement
        (elixir) lib/string/chars.ex:3: String.Chars.impl_for!/1
        (elixir) lib/string/chars.ex:22: String.Chars.to_string/1
        (ecto) lib/ecto/adapters/sql.ex:613: Ecto.Adapters.SQL.log/4
        (db_connection) lib/db_connection.ex:1186: DBConnection.log/6
        (ecto) lib/ecto/adapters/postgres/connection.ex:86: Ecto.Adapters.Postgres.Connection.execute/4
        (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
        (ecto) lib/ecto/adapters/sql.ex:542: Ecto.Adapters.SQL.struct/8
        (ecto) lib/ecto/repo/schema.ex:547: Ecto.Repo.Schema.apply/4
        (ecto) lib/ecto/repo/schema.ex:213: anonymous fn/14 in Ecto.Repo.Schema.do_insert/4
        (login) lib/login.ex:54: Login.register_user/1
        (web_api) lib/web_api/resolvers/users.ex:10: WebApi.Resolver.Users.registration/2
        (absinthe) lib/absinthe/resolution.ex:187: Absinthe.Resolution.call/2
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:187: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:149: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/4
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:135: Absinthe.Phase.Document.Execution.Resolution.do_resolve_fields/6
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:71: Absinthe.Phase.Document.Execution.Resolution.walk_result/5
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:53: Absinthe.Phase.Document.Execution.Resolution.perform_resolution/3
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:25: Absinthe.Phase.Document.Execution.Resolution.resolve_current/3
        (absinthe) lib/absinthe/pipeline.ex:253: Absinthe.Pipeline.run_phase/3
        (absinthe_plug) lib/absinthe/plug.ex:414: Absinthe.Plug.run_query/4

I’m not sure the answer to that. As shown above I had a project that gave me an error that looked the same to me. I followed the solution given here of deleting _build and recompiling, and that fixed it for me. So now I have a project that formerly seemed to reproduce this error, but I’m not sure how I would get it to reproduce it again.

1 Like