diff --git a/.changesets/remove-listen_for_error-helper.md b/.changesets/remove-listen_for_error-helper.md
new file mode 100644
index 000000000..a96923b75
--- /dev/null
+++ b/.changesets/remove-listen_for_error-helper.md
@@ -0,0 +1,6 @@
+---
+bump: major
+type: remove
+---
+
+Remove the `Appsignal.listen_for_error` helper. Use manual exception handling using `rescue => error` with the `Appsignal.report_error` helper instead.
diff --git a/lib/appsignal/helpers/instrumentation.rb b/lib/appsignal/helpers/instrumentation.rb
index 272dad0e8..091da084a 100644
--- a/lib/appsignal/helpers/instrumentation.rb
+++ b/lib/appsignal/helpers/instrumentation.rb
@@ -158,55 +158,6 @@ def monitor_and_stop(action:, namespace: nil, &block)
         Appsignal.stop("monitor_and_stop")
       end
 
-      # Listen for an error to occur and send it to AppSignal.
-      #
-      # Uses {.send_error} to directly send the error in a separate
-      # transaction. Does not add the error to the current transaction.
-      #
-      # Make sure that AppSignal is integrated in your application beforehand.
-      # AppSignal won't record errors unless {Appsignal.active?} is `true`.
-      #
-      # @example
-      #   # my_app.rb
-      #   # setup AppSignal beforehand
-      #
-      #   Appsignal.listen_for_error do
-      #     # my code
-      #     raise "foo"
-      #   end
-      #
-      # @see Transaction.set_tags
-      # @see Transaction.set_namespace
-      # @see .send_error
-      # @see https://docs.appsignal.com/ruby/instrumentation/integrating-appsignal.html
-      #   AppSignal integration guide
-      # @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
-      #   Exception handling guide
-      #
-      # @deprecated Use `rescue => error` with {.report_error} instead.
-      # @param tags [Hash, nil]
-      # @param namespace [String] the namespace for this error.
-      # @yield yields the given block.
-      # @return [Object] returns the return value of the given block.
-      def listen_for_error(
-        tags = nil,
-        namespace = Appsignal::Transaction::HTTP_REQUEST
-      )
-        stdout_and_logger_warning \
-          "The `Appsignal.listen_for_error` helper is deprecated. " \
-            "Please use `rescue => error` and `Appsignal.report_error` instead. " \
-            "Read our exception handling documentation: " \
-            "https://docs.appsignal.com/ruby/instrumentation/exception-handling.html"
-        yield
-      rescue Exception => error # rubocop:disable Lint/RescueException
-        send_error(error) do |transaction|
-          transaction.set_tags(tags) if tags
-          transaction.set_namespace(namespace) if namespace
-        end
-        raise error
-      end
-      alias :listen_for_exception :listen_for_error
-
       # Send an error to AppSignal regardless of the context.
       #
       # Records and send the exception to AppSignal.
diff --git a/spec/lib/appsignal_spec.rb b/spec/lib/appsignal_spec.rb
index ca8e10ec0..3b0a334ba 100644
--- a/spec/lib/appsignal_spec.rb
+++ b/spec/lib/appsignal_spec.rb
@@ -678,24 +678,6 @@ def on_start
   context "not active" do
     before { Appsignal._config = project_fixture_config("not_active") }
 
-    describe ".listen_for_error" do
-      let(:error) { ExampleException.new("specific error") }
-
-      it "reraises the error" do
-        expect do
-          Appsignal.listen_for_error { raise error }
-        end.to raise_error(error)
-      end
-
-      it "does not create a transaction" do
-        expect do
-          expect do
-            Appsignal.listen_for_error { raise error }
-          end.to raise_error(error)
-        end.to_not(change { created_transactions.count })
-      end
-    end
-
     describe ".send_error" do
       let(:error) { ExampleException.new("specific error") }
 
@@ -1307,77 +1289,6 @@ def on_start
       end
     end
 
-    describe ".listen_for_error" do
-      around { |example| keep_transactions { example.run } }
-
-      it "prints and logs a deprecation warning" do
-        err_stream = std_stream
-        logs =
-          capture_logs do
-            capture_std_streams(std_stream, err_stream) do
-              Appsignal.listen_for_error do
-                # Do nothing
-              end
-            end
-          end
-        expect(err_stream.read)
-          .to include("appsignal WARNING: The `Appsignal.listen_for_error` helper is deprecated.")
-        expect(logs).to contains_log(
-          :warn,
-          "The `Appsignal.listen_for_error` helper is deprecated."
-        )
-      end
-
-      it "records the error and re-raise it" do
-        expect do
-          expect do
-            Appsignal.listen_for_error do
-              raise ExampleException, "I am an exception"
-            end
-          end.to raise_error(ExampleException, "I am an exception")
-        end.to change { created_transactions.count }.by(1)
-
-        # Default namespace
-        expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
-        expect(last_transaction).to have_error("ExampleException", "I am an exception")
-        expect(last_transaction).to_not include_tags
-      end
-
-      context "with tags" do
-        it "adds tags to the transaction" do
-          expect do
-            expect do
-              Appsignal.listen_for_error("foo" => "bar") do
-                raise ExampleException, "I am an exception"
-              end
-            end.to raise_error(ExampleException, "I am an exception")
-          end.to change { created_transactions.count }.by(1)
-
-          # Default namespace
-          expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
-          expect(last_transaction).to have_error("ExampleException", "I am an exception")
-          expect(last_transaction).to include_tags("foo" => "bar")
-        end
-      end
-
-      context "with a custom namespace" do
-        it "adds the namespace to the transaction" do
-          expect do
-            expect do
-              Appsignal.listen_for_error(nil, "custom_namespace") do
-                raise ExampleException, "I am an exception"
-              end
-            end.to raise_error(ExampleException, "I am an exception")
-          end.to change { created_transactions.count }.by(1)
-
-          # Default namespace
-          expect(last_transaction).to have_namespace("custom_namespace")
-          expect(last_transaction).to have_error("ExampleException", "I am an exception")
-          expect(last_transaction).to_not include_tags
-        end
-      end
-    end
-
     describe ".set_error" do
       let(:err_stream) { std_stream }
       let(:stderr) { err_stream.read }