1
votes

In our code we're running:

Enum.uniq(something)

We're getting the following error:

 no function clause matching in Enum.uniq_list/3
 
 lib/enum.ex in Enum.uniq_list/3 at line 3655
 arg0 nil # THIS SHOULD NEVER HAPPEN
 arg1 %{86078 => true, 86079 => true, 86080 => true, 86081 => true, 86082 => true, 86083 => true, 86084 => true}
 arg2 #Function<217.29191728/1 in Enum.uniq/1>

Enum.uniq_list/3 is a private function in the code of Enum (see here):

defp uniq_list([head | tail], set, fun) do
  value = fun.(head)

  case set do
    %{^value => true} -> uniq_list(tail, set, fun)
    %{} -> [head | uniq_list(tail, Map.put(set, value, true), fun)]
  end
end

defp uniq_list([], _set, _fun) do
  []
end

The first time we call the function, the first argument is our something enumerable. From the error we know that it has some values (86078, 86079, ...).

What could be in the enumerable so the argument ends up being nil?

3
Hello Alan, it would be great if you could post a redacted example of the function parameter named something as it seems that the error depends heavily on the input parameter. - pasja
The issue is I cannot reproduce that myself, so I don't know what something is. In my tests I never get a nil value. - Alan
something needs to be a list - GavinBrelstaff

3 Answers

2
votes

I have been able to reproduce your error.

What seems to be happening is that you might be building an improper list somewhere. This can happen when, for instance, you try to append doing something like:

iex> l = [1, 2, 3]
[1, 2, 3]
iex> l = [l | 4]
[[1, 2, 3] | 4]

The | operator in this context should only be used to prepend, like: [4 | l]

You can reproduce the error doing:

iex> l = [86078, 86079, 86080, 86081, 86082, 86083, 86084 | nil]
[86078, 86079, 86080, 86081, 86082, 86083, 86084 | nil]
iex> Enum.uniq(l)
** (FunctionClauseError) no function clause matching in Enum.uniq_list/3    
    
    The following arguments were given to Enum.uniq_list/3:
    
        # 1
        nil
    
        # 2
        %{
          86078 => true,
          86079 => true,
          86080 => true,
          86081 => true,
          86082 => true,
          86083 => true,
          86084 => true
        }
    
        # 3
        #Function<217.29191728/1 in Enum.uniq/1>
    
    Attempted function clauses (showing 2 out of 2):
    
        defp uniq_list([head | tail], set, fun)
        defp uniq_list([], _set, _fun)
    
    (elixir 1.10.3) lib/enum.ex:3655: Enum.uniq_list/3
    (elixir 1.10.3) lib/enum.ex:3660: Enum.uniq_list/3
    (elixir 1.10.3) lib/enum.ex:3660: Enum.uniq_list/3

So, maybe you need to check if you are using | like that somewhere and fix it

1
votes
Enum.uniq( 1, 2, 3 )

produces a similar error message to that you are getting:

    (UndefinedFunctionError) function Enum.uniq/3 is undefined or private. Did you mean one of:
    
          * uniq/1
          * uniq/2
   (elixir) Enum.uniq(1, 2, 3)

Somehow you need to wrap your something in a list.

Enum.uniq( [1, 2, 3] )

It is possible that your something is a Enumerable but not a list - e.g. 1..3 - in that case you can use Enum.to_list(1..3) to get your list first. See Enum.to_list

0
votes

In my case, I have to check not to empty like below:

defp validate_contents([head | tail]) do
if tail != [] do
  validate_contents(tail)
end
end