Absinthe Resolver: FunctionClauseError When Optional Argument is Missing

I’m running into a FunctionClauseError in my Absinthe resolver when an optional argument (cursor) is omitted from the query. Here’s my setup:

I’m defining a paginated query for recent reviews, using cursor-based pagination:


@desc "Get recent reviews (cursor-based pagination)"
field :recent_reviews, :review_connection do
  arg :cursor, :string, default_value: nil
  arg :limit, :integer, default_value: 10

  resolve &Resolvers.list_recent_reviews/3
end

In my resolver, I expect both cursor and limit:


def list_recent_reviews(_parent, %{cursor: cursor, limit: limit}, _resolution) do
  Reviews.list_recent_reviews(cursor, limit)
end

However, when I run this GraphQL query without providing cursor:


query RecentReviews {
  recentReviews {
    nextCursor
    items {
      id
    }
  }
}

I get this error:


[error] ** (FunctionClauseError) no function clause matching in KaguyaWeb.GraphQL.Reviews.Resolvers.list_recent_reviews/3
    (kaguya 0.1.0) lib/kaguya_web/graphql/reviews/resolvers.ex:39:
    KaguyaWeb.GraphQL.Reviews.Resolvers.list_recent_reviews(%{}, %{limit: 10}, #Absinthe.Resolution{})

What I Found So Far

  • Even though I set default_value: nil in the schema, Absinthe omits cursor entirely from args when it’s not provided.
  • My function clause expects %{cursor: cursor, limit: limit}, but if cursor is missing, it doesn’t match, causing the FunctionClauseError.

Temporary Fix

I changed the resolver to use Map.get/3 to avoid a missing key issue:


def list_recent_reviews(_parent, args, _resolution) do
  cursor = Map.get(args, :cursor, nil)
  limit = Map.get(args, :limit, 10)

  Reviews.list_recent_reviews(cursor, limit)
end

This works fine, but I’m wondering:

  • Is this the best way to handle optional GraphQL arguments in Absinthe?
  • Shouldn’t default_value: nil ensure that cursor is always present in args, even if the user doesn’t provide it?
  • Why does Absinthe sometimes omit cursor entirely, rather than including it as nil?