Elixir’s “module is not available” error can drive you nuts.

But fear not:

After writing a lot of Elixir and seeing this error often, I’ll developed a few quick tricks that you can use to solve why your module is not available in seconds instead of minutes.

Here’s 4 quick things you can check.

Check Your Module Definition

This almost goes without saying, but every time I don’t check the module definition first, it turns out I’ve misspelled one of my module definitions.

Check the top (usually top) of your file for your defmodule function. Some things to look for are that everything is spelled correctly, i.e. App.User and not App.Users , that you have included your application name if needed, i.e. App.User not User , that you are using the proper punctuation, i.e. App.User.Note not App.UserNote .

Did You Forget to include alias ?

Sometimes, in a bout of “in the zone” programming, you may have written a call to a module that you believed you had aliased, but forgot to include the alias function call.

For example, trying to call User.full_name() when the full function call is App.User.full_name() would result in the module is not available error. App.User , in this case, would need to be aliased first.

Inspect Loaded Modules

Still can’t find the module? Well, one debugging trick is to check a list of all the currently loaded, user-defined modules in the application.

There’s two ways you can do this:

First, you can check the my_app.app compiled file in your /_build directory.

Specifically, this file is usually located in:

"_build/#{MIX_ENV}/lib/#{YOUR_APP_NAME_HERE}/ebin"

While this file may appear a bit cryptic, you can probably ascertain what the modules entry shows. It’s a list of user-defined modules available to your application from compilation.

The second trick is:

Use :application.get_key(:my_app, :modules) wherever the module is not available error is occurring. Combine this with the IO.inspect/1 function and it will show you all of the available user-defined Elixir modules at that point in time.

IO.inspect :application.get_key(:my_app, :modules)

It’s a quick way to see all the user-defined Elixir modules available to the :my_app application at that point in your Elixir application.

Using this Elixir debugging trick may allow you to catch if you have badly misspelled a module or perhaps forgot to include a module for compilation.

Which brings us to my last tip:

Make Sure Your Module is Available to Your Application

My last tip is the most complex in terms of implementation and understanding.

But here goes:

You need to check that your Elixir module is available to your application by telling the elixirc compiler to generate a .beam file for your module.

Why would the Elixir compiler not compile a .beam file? Well, 2 common reasons:

You placed the module in a directory outside of lib and did not

tell the compiler. You used the .exs extension instead of .ex

The first reason can be puzzling if you do not realize the problem. By default, the Elixir compiler only looks to compile files and load modules located in the lib directory of an Elixir application.

As your Elixir application complexity increases, you may decide to include Elixir modules that need to be compiled outside of the lib directory. A good example of this are modules that may be used for supporting tests such as mocks.

The solution to this problem is straightforward, but a bit hidden in the Elixir documentation.

You need to tell the Elixir compiler the directory where your modules are located.

To do this, you need to use the Elixir elixirc_paths option in your project configuration. All you need to do is set the elixirc_paths key to a list of paths of the directories that you want the Elixir compiler to compile.

Here’s the catch:

In many cases, you probably do not want to compile the same files across different environments.

For example, in a production environment, you may not want to compile the modules that you use for your test environment.

To get around this, we can use a function that we define in mix.exs that returns a different lists of paths depending on the environment.

In fact, this is exactly what Phoenix Framework does by default in new projects.

def project do [ ... elixirc_paths: elixirc_paths(Mix.env), ... ] end # Specifies which paths to compile per environment. defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"]

You can see in the code above the elixirc_paths/1 function includes the “test/support” directory in the Elixir compiler paths for the test environment, but not for other environments such as development.

Setting this directory in the Elixir compiler paths means that any modules defined within .ex extension files will automatically be compiled and their modules loaded for your application.

Which brings me to the second issue:

Another mistake that you may make is to use the .exs extension instead of the .ex extension. You may be defining Elixir modules that you need to compile for use in your application in files with a .exs extension.

The .exs extension is used for scripting. Like the .ex extension, .exs files are compiled, their modules loaded, and executed.

It is very well documented that .ex extension files get compiled down to .beam files. The modules in your compiled .beam files get loaded by your application automatically when the application starts.

However, the compiled BEAM bytecode from .exs files does not get output into a .beam file the way that .ex files do. They are, in essence, ephemeral. They are compiled, loaded, and executed, and then disappear. Hence, if you are trying to access a module in an .exs file from your application, it will fail with the “module not available” error.

Hope this information was helpful. If you have any questions or have another tip, feel free to leave a comment below.

This post is part of my series of Elixir Tutorials

Hey, I’m Adam. I’m guessing you just read this post from somewhere on the interwebs. Hope you enjoyed it. When I’m not writing these blog posts, I’m a freelance Elixir and Ruby developer and working on Calculate, a product which makes it easier for you to create software estimates for your projects. Feel free to leave a comment if you have any questions.

You can also follow me on the Twitters at: @DeLongShot