`Ash.Type.NewType` defines multiple GraphQL types with the same name.

I have the following custom type
defmodule MyApp.Types.DayOfWeek do
@moduledoc false

use Ash.Type.NewType,
subtype_of: :atom,
constraints: [one_of: [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]]

def graphql_input_type(_), do: :day_of_week
def graphql_type, do: :day_of_week
def graphql_type(_), do: :day_of_week
end
defmodule MyApp.Types.DayOfWeek do
@moduledoc false

use Ash.Type.NewType,
subtype_of: :atom,
constraints: [one_of: [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]]

def graphql_input_type(_), do: :day_of_week
def graphql_type, do: :day_of_week
def graphql_type(_), do: :day_of_week
end
That is used in two resources
defmodule ResourceA do
...
attributes do
...
attribute :days_of_week, {:array, MyApp.Types.DayOfWeek}
end
end


defmodule ResourceB do
...
attributes do
...
attribute :day_of_week, MyApp.Types.DayOfWeek}
end

relationships do
belongs_to :a_resource, ResourceA, allow_nil?: false
end
end
defmodule ResourceA do
...
attributes do
...
attribute :days_of_week, {:array, MyApp.Types.DayOfWeek}
end
end


defmodule ResourceB do
...
attributes do
...
attribute :day_of_week, MyApp.Types.DayOfWeek}
end

relationships do
belongs_to :a_resource, ResourceA, allow_nil?: false
end
end
Also I've defined a Scalar and imported it to schema
scalar :day_of_week do
parse(&parse_day_of_week/1)
serialize(& &1)
end

defp parse_day_of_week(%Absinthe.Blueprint.Input.String{value: value}) do
case MyApp.Types.DayOfWeek.cast_input(value, []) do
{:ok, value} -> {:ok, value}
_ -> :error
end
end
scalar :day_of_week do
parse(&parse_day_of_week/1)
serialize(& &1)
end

defp parse_day_of_week(%Absinthe.Blueprint.Input.String{value: value}) do
case MyApp.Types.DayOfWeek.cast_input(value, []) do
{:ok, value} -> {:ok, value}
_ -> :error
end
end
9 Replies
Myrmyr
MyrmyrOP3y ago
When I try to run it I get the following message:
== Compilation error in file lib/my_app/schema.ex ==
** (Absinthe.Schema.Error) Compilation failed:
---------------------------------------
## Locations
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/lib/my_app/graphql/types/common_types.ex:63

Type name "DayOfWeek" is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system
---------------------------------------
## Locations
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/lib/my_app/graphql/types/common_types.ex:63

Absinthe type identifier :day_of_week is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system


(absinthe 1.7.1) lib/absinthe/schema.ex:392: Absinthe.Schema.__after_compile__/2
(stdlib 4.1.1) lists.erl:1350: :lists.foldl/3
(elixir 1.14.1) lib/kernel/parallel_compiler.ex:346: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
== Compilation error in file lib/my_app/schema.ex ==
** (Absinthe.Schema.Error) Compilation failed:
---------------------------------------
## Locations
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/lib/my_app/graphql/types/common_types.ex:63

Type name "DayOfWeek" is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system
---------------------------------------
## Locations
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/deps/ash_graphql/lib/resource/resource.ex:2358
my_app/lib/my_app/graphql/types/common_types.ex:63

Absinthe type identifier :day_of_week is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system


(absinthe 1.7.1) lib/absinthe/schema.ex:392: Absinthe.Schema.__after_compile__/2
(stdlib 4.1.1) lists.erl:1350: :lists.foldl/3
(elixir 1.14.1) lib/kernel/parallel_compiler.ex:346: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
- When I use another custom type that does not use NewType everything works fine. - When I remove my custom scalar there's one Location less in the error log - Before I've added def graphql_type, do: :day_of_week, there was more errors with less Locations per error - Just to be sure I've added config :ash_graphql, :default_managed_relationship_type_name_template, :action_name per some other issue here but it did not help in any way Used Versions: - Ash - 2.6.28 - Ash Graphql - 0.23.1
ZachDaniel
ZachDaniel3y ago
Interesting…I think we’re missing an Enum.uniq somewhere Will look into this later today. So to double check this issue persists even when you remove your manual type? You shouldn't have to add that type, BTW, Ash will do the enum definition
Myrmyr
MyrmyrOP3y ago
No, when I change this type to another custom type in resources attribute definition, that do not use Ash.Type.NewType it's working normally, so I think it's specific to Ash.Type.NewType
ZachDaniel
ZachDaniel3y ago
Well, what I'm getting at is removing this:
scalar :day_of_week do
parse(&parse_day_of_week/1)
serialize(& &1)
end

defp parse_day_of_week(%Absinthe.Blueprint.Input.String{value: value}) do
case MyApp.Types.DayOfWeek.cast_input(value, []) do
{:ok, value} -> {:ok, value}
_ -> :error
end
end
scalar :day_of_week do
parse(&parse_day_of_week/1)
serialize(& &1)
end

defp parse_day_of_week(%Absinthe.Blueprint.Input.String{value: value}) do
case MyApp.Types.DayOfWeek.cast_input(value, []) do
{:ok, value} -> {:ok, value}
_ -> :error
end
end
Myrmyr
MyrmyrOP3y ago
Yeah, colleague just reminded my about Ash.Type.Enum in the code review, so I've switched to that now Removing that, for me removes just one of 5 Locations from the warning
ZachDaniel
ZachDaniel3y ago
🤔 very interesting Okay I just released 0.23.2 that should fix the issue Well, it might 😄
Myrmyr
MyrmyrOP3y ago
Sadly this didn't fix it. After some debugging I think it's because the NewType is being defined per resource as we can see in resource.ex:2297. I've inserted IO.inspect into get_auto_enums and after resource.ex:2342 and when my type was based on Ash.Type.NewType it was in these inspects, but when I've switched back to Ash.Type.Enum it wasn't. I'm guessing that it's being treated as "inline enum", so when you defined enum like this:
attribute :some_enum, :atom do
constraints one_of: [:a, :b, :c]
end
attribute :some_enum, :atom do
constraints one_of: [:a, :b, :c]
end
because in these inspects I see "types" that are defined like this, the main difference is that for those it has unique name per resource. It would work without defining def graphql_input, but for some reason to types defined like that the _input postfix isn't added like to those "inline enums", so there are same atoms returned for type_name and additional_type_name in resource.ex:2304. When def graphql_input is defined, it uses this name everywhere, so there are more Locations with conflicts for Absinthe, as seen before.
ZachDaniel
ZachDaniel3y ago
Ah, okay interesting. So I think what we need to do is basically not include that as an "auto enum" if it has a type name, and instead define those up front. @Myrmyr I won't have time to fix this immediately, and using Ash.Type.Enum is a workaround, right? If so, would you mind opening an issue in ash_graphql so we can track this/improve it later?
Myrmyr
MyrmyrOP3y ago
I would say that using Ash.Type.Enum is the proper solution rather than a workaround but yeah, it works. Sure, I'm on it.

Did you find this page helpful?