System.get_env("MY_API_KEY") works in iex console but not in Development

Hello all,

I’ve set up an API key in my dev.exs config but my Phoenix app isn’t reading it. It works in iex console.

sendgrid_api_key =
  System.get_env("SENDGRID_API_KEY") ||
    raise """
    environment variable SENDGRID_API_KEY is missing.
    """

Leads to

$ iex -S mix phx.server

** (RuntimeError) environment variable SENDGRID_API_KEY is missing.

But in IEX console

iex> System.get_env("SENDGRID_API_KEY")  

Outputs the correct key.

I set this variable using

$ export SENDGRID_API_KEY='MY_API_KEY'

If this is in your config/dev.exs:

sendgrid_api_key =
  System.get_env("SENDGRID_API_KEY") ||
    raise """
    environment variable SENDGRID_API_KEY is missing.
    """

Then everything would generally appear to be correct. How are you starting the iex session that is working? You could also verify with env | grep SENDGRID_API_KEY in the terminal before running iex -S mix phx.server.

If that doesn’t work then it will probably be necessary to look at the rest of your config.exs and config/dev.exs. Another debugging step would be to add IO.inspect(System.get_env()) right before you try to read the environment variable.

Correct, that is in my config/dev.exs

env | grep SENDGRID_API_KEY works propery

I added IO.inspect

sendgrid_api_key =
  IO.inspect(System.get_env("SENDGRID_API_KEY")) ||
    raise """
    environment variable SENDGRID_API_KEY is missing.
    """

This outputs nil to the console.

how about just

mix phx.server

Thanks for the idea, just tried it and still doesn’t work. :frowning:

I assume this is copied from a website?

Have you tried to delete and manually enter the argument to System.get_env/1 to make sure it doesn’t contain any unprintable charaters from copying?

this is copied from prod.secret.exs

secret_key_base =
  System.get_env("SECRET_KEY_BASE") ||
    raise """
    environment variable SECRET_KEY_BASE is missing.
    You can generate one by calling: mix phx.gen.secret
    """

I tried IO.inspecting System.get_env/0 and that worked, but the environment variables are all different than what I am seeing in iex console. I am wondering if it has something to do with the new zsh console on mac. It looked to me like the things output in development were from my bash environment.

Will report back as I dig deeper.

So, do you have the env vars in your ~/.zshrc file? Or, do you use the direnv program with a local .envrc file (in your repo)?

I keep them in my ~/.zshrc

I think that zsh has env. So should see SECRET_KEY_BASE in the output from env command.

So I took a recommendation from @NobbZ and changed the code to output all the env variables:

sendgrid_api_key =
  System.get_env() |> Enum.each(fn {k, v} -> IO.puts("#{k} => #{v}") end)

When I run iex -S mix phx.server 59 environment variables show (NOT including the one I want), but when I run iex -S mix only 39 show (including the one I want).

Solution
I took a gamble and just ran $ export SENDGRID_API_KEY='MY_API_KEY' again, now everything is working! :rofl:

Not sure why it didn’t work the first time, oh well. My guess is quitting terminal and reloading it might have also fixed this.

1 Like