{"record":{"id":"d9ca4c7aa08990e7","repo":"ruby-concurrency/concurrent-ruby","slug":"probe-is-not-resolvable","errorCode":null,"errorMessage":"probe is not Resolvable","messagePattern":"probe is not Resolvable","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb","lineNumber":1264,"sourceCode":"      end\n    end\n\n    private_constant :OnThread\n\n    class AbstractSignal < Synchronization::Object\n      safe_initialization!\n    end\n\n    private_constant :AbstractSignal\n\n    class Ask < AbstractSignal\n      attr_reader :message, :probe\n\n      def initialize(message, probe)\n        super()\n        @message = message\n        @probe   = probe\n        raise ArgumentError, 'probe is not Resolvable' unless probe.is_a? Promises::Resolvable\n      end\n    end\n\n    private_constant :Ask\n\n    module HasFrom\n\n      # @return [Pid]\n      attr_reader :from\n\n      # @!visibility private\n      def initialize(from)\n        # noinspection RubySuperCallWithoutSuperclassInspection\n        super()\n        @from = from\n      end\n\n      # @return [true, false]","sourceCodeStart":1246,"sourceCodeEnd":1282,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb#L1246-L1282","documentation":"`Ask` is the internal signal ErlangActor uses for request/response: it pairs the caller's message with a `probe` future that gets resolved with the reply. Its constructor enforces `probe.is_a?(Concurrent::Promises::Resolvable)` and raises ArgumentError otherwise. The built-in `ask`/`ask_op` paths construct the probe for you (`ask_op(message, probe = Promises.resolvable_future)`), so hitting this error means a probe of the wrong kind was threaded through — typically a plain `Promises.future` (which is resolvable-scheduled, not a Resolvable) or a custom future object.","triggerScenarios":"`pid.ask_op(message, Concurrent::Promises.future { compute })` — a plain future is not a Promises::Resolvable. Monkey-patching or reimplementing ask and passing a Task, an `Edge::Future`, or any custom future class as the probe. Constructing Ask-style signals manually against the internal protocol (Ask itself is a private_constant).","commonSituations":"Substituting another future implementation for the probe; copying library internals into app code during upgrades; version drift where the resolvable contract on Promises objects changed between edge releases.","solutions":["Use the public `pid.ask(message)` / `pid.ask!` which create a `resolvable_future` probe internally.","If you call `ask_op` with your own probe, create it with `Concurrent::Promises.resolvable_future` — that object satisfies Promises::Resolvable.","Bridge custom futures: resolve a `resolvable_future` when your custom future completes, and pass the resolvable as the probe.","Treat Ask and other private constants as off-limits; go through Pid's public API."],"exampleFix":"// before\nprobe = Concurrent::Promises.future { compute } # not Resolvable\npid.ask_op(message, probe)\n\n// after\nprobe = Concurrent::Promises.resolvable_future # a Promises::Resolvable\npid.ask_op(message, probe)","handlingStrategy":"type-guard","validationCode":"probe = Concurrent::Promises.resolvable_future\nraise ArgumentError, 'probe is not Resolvable' unless resolvable_probe?(probe)\npid.ask_op(message, probe)","typeGuard":"def resolvable_probe?(obj)\n  obj.is_a?(Concurrent::Promises::Resolvable)\nend","tryCatchPattern":null,"preventionTips":["Prefer the public pid.ask / pid.ask! — they build the resolvable probe for you.","Create probes only with Concurrent::Promises.resolvable_future.","Do not construct private signal classes (Ask, AbstractSignal) yourself."],"tags":["concurrent-ruby","concurrent-ruby-edge","erlang-actor","ask","promises","argumenterror"],"backgroundTag":"type-validation-failed","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}