diff --git a/app/channels/graphql_channel.rb b/app/channels/graphql_channel.rb
index 4e2edc84..3ec20c44 100644
--- a/app/channels/graphql_channel.rb
+++ b/app/channels/graphql_channel.rb
@@ -1,4 +1,4 @@
-# typed: strict
+# typed: true
 # frozen_string_literal: true
 
 class GraphQLChannel < ApplicationCable::Channel
@@ -135,6 +135,6 @@ def pretty(data)
     return "" if data.blank?
 
     data = JSON.parse(data) if data.is_a?(String)
-    PP.pp(data, "")
+    PP.pp(data, +"")
   end
 end
diff --git a/app/controllers/concerns/graphql/querying.rb b/app/controllers/concerns/graphql/querying.rb
index 74637c93..5cbc5851 100644
--- a/app/controllers/concerns/graphql/querying.rb
+++ b/app/controllers/concerns/graphql/querying.rb
@@ -21,7 +21,13 @@ def current_user; end
   end
   def query(name, variables = {})
     context = { current_user: }
-    variables.deep_transform_keys! { |key| key.to_s.camelize(:lower) }
+    variables.deep_transform_keys! do |key|
+      if key.is_a?(Symbol)
+        key.to_s.camelize(:lower)
+      else
+        key
+      end
+    end
     Schema.queries!.execute(name, variables:, context:)
   end
 
diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb
index 04db06b8..8188cbea 100644
--- a/app/controllers/errors_controller.rb
+++ b/app/controllers/errors_controller.rb
@@ -2,7 +2,16 @@
 # frozen_string_literal: true
 
 class ErrorsController < ApplicationController
-  # == Actions ==
+  # == Initialization
+  def initialize(...)
+    super
+    @exceptions_app = T.let(
+      ActionDispatch::PublicExceptions.new(Rails.public_path),
+      ActionDispatch::PublicExceptions,
+    )
+  end
+
+  # == Actions
   # GET /404
   def not_found
     error(
@@ -47,6 +56,9 @@ def unauthorized
   private
 
   # == Helpers
+  sig { returns(ActionDispatch::PublicExceptions) }
+  attr_reader :exceptions_app
+
   sig do
     params(
       status: Symbol,
@@ -57,10 +69,15 @@ def unauthorized
   def error(status:, title:, description:)
     data = query!("ErrorPageQuery")
     code = Rack::Utils.status_code(status)
-    render(
-      inertia: "ErrorPage",
-      props: { data:, title:, description:, code: },
-      status:,
-    )
+    if request.format == :html
+      render(
+        inertia: "ErrorPage",
+        props: { data:, title:, description:, code: },
+        status:,
+      )
+    else
+      message = Rack::Utils::HTTP_STATUS_CODES[code]
+      render(plain: message, status:)
+    end
   end
 end
diff --git a/lib/graphql_ext/connections.rb b/lib/graphql_ext/connections.rb
index eb7f8c5d..c2d70dbf 100644
--- a/lib/graphql_ext/connections.rb
+++ b/lib/graphql_ext/connections.rb
@@ -6,16 +6,45 @@
 
 module GraphQL::Connections
   module Stable
-    class << self
-      extend T::Sig
+    extend T::Sig
 
-      # == Plugin
-      sig { params(defn: T.untyped, options: T::Hash[Symbol, T.untyped]).void }
-      def use(defn, options = {})
-        schema = T.let(defn.is_a?(Class) ? defn : defn.target,
-                       T.class_of(GraphQL::Schema))
-        schema.connections.add(ActiveRecord::Relation, self)
+    # == Plugin
+    sig { params(defn: T.untyped, options: T::Hash[Symbol, T.untyped]).void }
+    def self.use(defn, options = {})
+      schema = T.let(defn.is_a?(Class) ? defn : defn.target,
+                     T.class_of(GraphQL::Schema))
+      schema.connections.add(ActiveRecord::Relation, self)
+    end
+  end
+
+  module PrimaryKey
+    class Base
+      module Extension
+        extend T::Sig
+        extend T::Helpers
+
+        requires_ancestor { Base }
+
+        def has_next_page
+          if first
+            nodes.any? && items_exist?(
+              type: :query,
+              search: nodes.last[primary_key],
+              page_type: :next,
+            )
+          elsif before
+            items_exist?(
+              type: :cursor,
+              search: before_cursor,
+              page_type: :next,
+            )
+          else
+            false
+          end
+        end
       end
+
+      prepend Extension
     end
   end
 end