Cannot find a file in Elixir 1.4.4

Hi everyone,

My application uses erlavro to encode messages in Avro format and produce to Kafka, schema files are stored under schema directory, it worked well before, but today I start it and receive following error

** (Mix) Could not start application collector: Collector.Application.start(:normal, []) returned an error: shutdown: failed to start child: Collector.AvroEncoder
** (EXIT) an exception was raised:
    ** (FunctionClauseError) no function clause matching in :avro_schema_store.import_files/2
        (erlavro) /root/collector/collector-master/deps/erlavro/src/avro_schema_store.erl:108: :avro_schema_store.import_files(['/schema/click.avsc'], #Reference<0.2922484918.3488219137.85703>)
        (collector) lib/collector/avro_encoder.ex:9: Collector.AvroEncoder.init/1
        (stdlib) gen_server.erl:365: :gen_server.init_it/2
        (stdlib) gen_server.erl:333: :gen_server.init_it/6
        (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

My code isn’t changed, it worked when I use Elixir 1.4.2, now I update to 1.4.4 and it crash. I think schema files are not found, but I don’t know why.
Environment

Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.4.4
Ubuntu 16.04.2 64 bit

What should I do?
Thanks

The error indicates that a function cannot be matched to the call:

:avro_schema_store.import_files(['/schema/click.avsc'], #Reference<0.2922484918.3488219137.85703>)

Looking at the code, the function signature is:

-define(IS_STORE(S), (is_integer(S) orelse is_atom(S))).

-spec import_files([filename()], store()) -> store().
import_files(Files, Store) when ?IS_STORE(Store) ->
  lists:foldl(fun(File, S) -> import_file(File, S) end, Store, Files).

Meaning that store() needs be be either an atom or an integer. It appears you are passing a #Reference.

That #Reference comes from a call to ets:new which now returns other than an integer or atom

Hope that at least gives you a start on debugging…

1 Like

This is a bug in erlavro. It seems the erlavro project assumed ETS table identifiers to be atoms or integers. This was never correct since the table idenfier was documented by be “an atom or an opaque term”. The opaque term happened to be an integer until OTP 19 but was changed to a reference in OTP 20 for improved performance of creating tables.

Either fixing the library or downgrading to OTP 19 (until there’s a fix) are the solutions.

3 Likes

Thank you @michalmuskala, now I know what to do