ruby-concurrency/concurrent-ruby · error · TypeError

Value (#{value.class}) '#{value}' #{message} any of: #{types

Error message

Value (#{value.class}) '#{value}' #{message} any of: #{types.join('; ')}.

What it means

Concurrent::Actor::TypeCheck provides the bang helpers `Type!`, `Match!`, and `Child!` used throughout the Edge Actor internals (e.g. `initialize_core` requires a `Core`; spawn validates names and classes). When a value fails the allowed-type test, `TypeCheck.error` raises TypeError with a composed message naming the value's class, the value itself, the failure kind ('is not' for Type!, 'is not matching' for Match!, 'is not child' for Child!), and the accepted types. `Type?` checks `value.is_a?(t)`, `Match?` uses `t === value`, and `Child?` requires value to be a Class with `value <= t`.

Source

Thrown at lib/concurrent-ruby-edge/concurrent/actor/type_check.rb:42

            TypeCheck.error(value, 'is not matching', types)
        value
      end

      def Child?(value, *types)
        Type?(value, Class) &&
            types.any? { |t| value <= t }
      end

      def Child!(value, *types)
        Child?(value, *types) or
            TypeCheck.error(value, 'is not child', types)
        value
      end

      private

      def self.error(value, message, types)
        raise TypeError,
              "Value (#{value.class}) '#{value}' #{message} any of: #{types.join('; ')}."
      end
    end
  end
end

View on GitHub (pinned to 0b88d5ff75)

Solutions

  1. Read the message: it lists the accepted types — convert or replace the value with one of those types.
  2. If the check was Child!, make the value a Class that inherits (or includes) an accepted type, e.g. `class MyWorker < Concurrent::Actor::Context`.
  3. If the check was Type!/Match!, pass an instance matching one of the listed types.
  4. Pin matching versions of concurrent-ruby and concurrent-ruby-edge in your Gemfile so class identities line up.

Example fix

// before
Child!(MyWorker, Concurrent::Actor::Context)
# MyWorker is a plain class ->
# Value (Class) 'MyWorker' is not child any of: Concurrent::Actor::Context.

// after
class MyWorker < Concurrent::Actor::Context; end
Child!(MyWorker, Concurrent::Actor::Context)
Defensive patterns

Strategy: type-guard

Type guard

def type_check_ok?(value, *types)
  types.any? { |t| value.is_a?(t) }
end

def child_check_ok?(value, *types)
  value.is_a?(Class) && types.any? { |t| value <= t }
end

Try / catch

begin
  Child!(klass, Concurrent::Actor::Context)
rescue TypeError => e
  # e.message lists accepted types; wrap value in an adapter or fix the caller
  raise InvalidActorInput, e.message
end

Prevention

When it happens

Trigger: Passing a wrong-typed value into an Actor API that type-checks: a non-Reference where a Concurrent::Actor::Reference is required, a non-String/Symbol actor name, or calling `Child!(MyClass, Concurrent::Actor::Context)` when MyClass does not inherit Context (Child! additionally demands the value be a Class at all). Also raised from your own code when you include Concurrent::Actor::TypeCheck and call the bang helpers with a failing value.

Common situations: Wrapping actor references in decorator/delegate objects and passing the wrapper where the real Reference is required; version skew between concurrent-ruby and concurrent-ruby-edge where internal constants moved; duck-typed classes that never actually subclass the required base.

Related errors


AI-assisted analysis of ruby-concurrency/concurrent-ruby@0b88d5ff75 (2026-08-21). Data as JSON: /api/errors/a63dcf7860699c49. Report an issue: GitHub.