0

I'm having trouble getting my Elixir apps to read the MIX_ENV variable from the local environment on my Mac. For example, running the command

$ MIX_ENV=prod iex -S mix

throws the following error:

** (FunctionClauseError) no function clause matching in String.split/3    

    The following arguments were given to String.split/3:

        # 1
        nil

        # 2
        " "

        # 3
        []

    Attempted function clauses (showing 4 out of 4):

        def split(string, %Regex{} = pattern, options) when is_binary(string)
        def split(string, "", options) when is_binary(string)
        def split(string, pattern, []) when is_tuple(pattern) or is_binary(string)
        def split(string, pattern, options) when is_binary(string)

    (elixir) lib/string.ex:407: String.split/3
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:888: :erl_eval.expr_list/6
    (stdlib) erl_eval.erl:240: :erl_eval.expr/5
    (stdlib) erl_eval.erl:232: :erl_eval.expr/5
    (stdlib) erl_eval.erl:888: :erl_eval.expr_list/6
    (stdlib) erl_eval.erl:411: :erl_eval.expr/5
    (stdlib) erl_eval.erl:126: :erl_eval.exprs/5

This also occurs if I set the MIX_ENV in a separate step.

From the documentation at https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html, it looks to me like I'm doing this correctly, but it would seem that I'm not. Is there a different way that I need to set this?

As noted, I'm working on a Mac, Mojave 10.14.6, and my Elixir version is 1.8.1.

skwidbreth
  • 7,888
  • 11
  • 58
  • 105
  • Sounds like you are trying to get to `Mix.env` from your runtime code. Releases / `prod` env do not include `mix` application by default, that is why `Mix.env` does not get populated in `prod` and you’ll get an aexception raised in the release. For starters you might try to add `:mix` to the list of included applications in `mix.exs`. Of it helps, try to eliminate calls to `Mix.whatever` from your runtime code. – Aleksei Matiushkin Aug 26 '19 at 15:01
  • @AlekseiMatiushkin ah yes, I see that the issue is specific to setting `MIX_ENV=prod` - it worked with `dev` and `test`. However, adding `:mix` to the included applications didn't seem to change this behavior. The app is deployed to Heroku, and the Procfile I use there states `MIX_ENV=prod elixir --sname my_app -S mix phx.server` - I'm not clear on why this would work there but not on my machine. – skwidbreth Aug 26 '19 at 15:20
  • The command line you’ve posted did not run `phx.server`, it started `iex` only. – Aleksei Matiushkin Aug 26 '19 at 15:30
  • True - and I apologize for being a little all over the place with that - but I am getting the same error when running `MIX_ENV=prod mix phx.server` as well. – skwidbreth Aug 26 '19 at 15:33
  • 1
    Have you posted the _full_ stacktrace btw? It’s weird it fails in the core call. – Aleksei Matiushkin Aug 26 '19 at 15:33
  • @AlekseiMatiushkin in this context, I'm not sure how to get the full stacktrace - could you enlighten me on that? Thanks! – skwidbreth Aug 26 '19 at 18:03

1 Answers1

1

I would check your configuration. For me a lot of times this comes from prod expecting an environment variable to be set.

My guess is you have some code that looks something like this:

:my_app
|> Application.get_env(:some_config)
|> String.split(" ")
|> do_something_else()

Then in your config/config.exs or config/dev.exs you probably have something like this:

config :my_app, :some_config, "some value"

Then your config/prod.exs might have something like this:

config :my_app, :some_config, System.get_env("MY_ENV_VAR")

If MY_ENV_VAR is not set, but you run your app in prod (for example doing MIX_ENV=prod iex -S mix), Application.get_env(:my_app, :some_config) will return nil, which you would then be trying to split like it's a string.

This is just a guess based on my experience, but your stack trace would lead me to believe I'm wrong.

Brett Beatty
  • 5,690
  • 1
  • 23
  • 37
  • Ah, that was it! Thanks, Brett. Because of the limited stacktrace, I didn't realize that this was coming from within my own code - I incorrectly assumed (surprise) that the error was tied to a more fundamental process that I couldn't easily peer into. – skwidbreth Aug 27 '19 at 14:04