ruby-concurrency/concurrent-ruby · error · Concurrent::Agent::Error
agent is not failed
Error message
agent is not failed
What it means
Agent#restart is the recovery path for an agent in :fail error mode whose action raised: it replaces the value, optionally clears queued actions, and resumes processing. Restoring a healthy agent is meaningless (its state is live and actions are flowing), so restart raises Agent::Error unless failed? is true.
Source
Thrown at lib/concurrent-ruby/concurrent/agent.rb:427
# then un-fails the Agent so that action dispatches are allowed again. If
# the `:clear_actions` option is give and true, any actions queued on the
# Agent that were being held while it was failed will be discarded,
# otherwise those held actions will proceed. The `new_value` must pass the
# validator if any, or `restart` will raise an exception and the Agent will
# remain failed with its old {#value} and {#error}. Observers, if any, will
# not be notified of the new state.
#
# @param [Object] new_value the new value for the Agent once restarted
# @param [Hash] opts the configuration options
# @option opts [Symbol] :clear_actions true if all enqueued but unprocessed
# actions should be discarded on restart, else false (default: false)
# @return [Boolean] true
#
# @raise [Concurrent:AgentError] when not failed
def restart(new_value, opts = {})
clear_actions = opts.fetch(:clear_actions, false)
synchronize do
raise Error.new('agent is not failed') unless failed?
raise ValidationError unless ns_validate(new_value)
@current.value = new_value
@error.value = nil
@queue.clear if clear_actions
ns_post_next_job unless @queue.empty?
end
true
end
class << self
# Blocks the current thread (indefinitely!) until all actions dispatched
# thus far to all the given Agents, from this thread or nested by the
# given Agents, have occurred. Will block when any of the agents are
# failed. Will never return if a failed Agent is restart with
# `:clear_actions` true.
#
# @param [Array<Concurrent::Agent>] agents the Agents on which to waitView on GitHub (pinned to 0b88d5ff75)
Solutions
- Guard the call: agent.restart(new_value) if agent.failed?.
- In supervision loops, re-check failed? each cycle and restart at most once per observed failure.
- If you only want to change a healthy agent's value, use the normal update path (agent << new_value or agent.send { |old| ... }) - restart is not a setter.
Example fix
# before agent.restart(fresh_value) # raises unless the agent is failed # after if agent.failed? agent.restart(fresh_value, clear_actions: true) else agent << fresh_value # normal state change end
Defensive patterns
Strategy: validation
Validate before calling
agent.restart(new_value, clear_actions: true) if agent.failed?
Try / catch
begin agent.restart(new_value) rescue Concurrent::Agent::Error agent << new_value # healthy agent: normal state change instead end
Prevention
- Always gate restart on agent.failed?.
- Restart at most once per observed failure; re-check failed? on every supervision cycle.
- Use agent << value or agent.send { |old| ... } for ordinary state changes - restart is recovery-only.
When it happens
Trigger: agent.restart(value) on an agent that never failed, or on one that already restarted - e.g. an unconditional restart in a supervision/recovery loop, or two threads that both observed the failure and both call restart (the second raises).
Common situations: Defensive supervision code calling restart 'just in case' each cycle; retry loops that restart on every iteration although only the first call is valid; races between multiple monitors of the same agent.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- unrecognized error mode
- no action given
- unbuffered channels cannot have a capacity
- capacity must be at least 1 for this buffer type
- no block given
AI-assisted analysis of ruby-concurrency/concurrent-ruby@0b88d5ff75 (2026-08-21).
Data as JSON: /api/errors/7d4fe058f9addb98.
Report an issue: GitHub.