{"record":{"id":"506508558adf300c","repo":"ruby-concurrency/concurrent-ruby","slug":"concurrent-timeouterror","errorCode":null,"errorMessage":"Concurrent::TimeoutError","messagePattern":"Concurrent::TimeoutError","errorType":"exception","errorClass":"Concurrent::TimeoutError","httpStatus":null,"severity":"error","filePath":"lib/concurrent-ruby/concurrent/agent.rb","lineNumber":378,"sourceCode":"    # @return [Boolean] true if all actions complete before timeout else false\n    #\n    # @!macro agent_await_warning\n    def await_for(timeout)\n      wait(timeout.to_f)\n    end\n\n    # Blocks the current thread until all actions dispatched thus far, from this\n    # thread or nested by the Agent, have occurred, or the timeout (in seconds)\n    # has elapsed.\n    #\n    # @param [Float] timeout the maximum number of seconds to wait\n    # @return [Boolean] true if all actions complete before timeout\n    #\n    # @raise [Concurrent::TimeoutError] when timeout is reached\n    #\n    # @!macro agent_await_warning\n    def await_for!(timeout)\n      raise Concurrent::TimeoutError unless wait(timeout.to_f)\n      true\n    end\n\n    # Blocks the current thread until all actions dispatched thus far, from this\n    # thread or nested by the Agent, have occurred, or the timeout (in seconds)\n    # has elapsed. Will block indefinitely when timeout is nil or not given.\n    #\n    # Provided mainly for consistency with other classes in this library. Prefer\n    # the various `await` methods instead.\n    #\n    # @param [Float] timeout the maximum number of seconds to wait\n    # @return [Boolean] true if all actions complete before timeout else false\n    #\n    # @!macro agent_await_warning\n    def wait(timeout = nil)\n      latch = Concurrent::CountDownLatch.new(1)\n      enqueue_await_job(latch)\n      latch.wait(timeout)","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/lib/concurrent-ruby/concurrent/agent.rb#L360-L396","documentation":"`Agent#await_for!(timeout)` blocks until every action dispatched so far to the agent (from the current thread or nested by the agent) has completed, or the timeout elapses. The bang variant raises Concurrent::TimeoutError when `wait(timeout)` returns false — the action queue did not drain in time — while the non-bang `await_for(timeout)` returns false instead. Timeouts almost always mean the agent's executor is saturated, actions are slow or blocking, or the dispatch chain is longer than the budget assumes.","triggerScenarios":"`agent.await_for!(0.1)` right after dispatching expensive actions; awaiting from inside the agent's own action chain in a way that only the agent can complete (self-deadlock); a starved shared executor (`Concurrent.global_fast_executor`) shared with other heavy work.","commonSituations":"Test suites asserting agent convergence with tight timeouts; bulk updates to one agent in a loop then awaiting; actions performing I/O or sleeping on the agent's thread pool.","solutions":["Switch to the boolean form and branch on it: `agent.await_for(5)` returns true/false instead of raising.","Increase or remove the timeout (`await` waits indefinitely) when convergence is guaranteed.","Profile the dispatched actions — move blocking I/O or heavy computation out of agent actions into tasks.","Check for self-deadlock: an action (or its nested dispatches) must not wait on the same agent's completion."],"exampleFix":"// before\nagent.await_for!(0.1) # raises Concurrent::TimeoutError under load\n\n// after\nunless agent.await_for(5)\n  logger.warn 'agent did not settle within 5s'\nend","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  agent.await_for!(5)\nrescue Concurrent::TimeoutError\n  # queue not drained; log, extend the budget, or degrade gracefully\nend","preventionTips":["Prefer boolean await_for over the bang variant in production code.","Keep agent actions short and non-blocking.","Never wait on an agent from inside its own action chain.","Size timeouts from measured action cost, not constants."],"tags":["concurrent-ruby","agent","timeout","await"],"backgroundTag":"operation-timed-out","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}