crewAIInc/crewAI · error · ValueError
Multion client is not initialized.
Error message
Multion client is not initialized.
What it means
MultiOnTool._run guards against a None self.multion before calling self.multion.browse(...). Under normal construction the client is always created in __init__, so this ValueError mostly appears when the attribute was explicitly set to None, the object was built via model_construct-style paths skipping __init__, or serialization/deserialization lost the client.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/multion_tool/multion_tool.py:69
self.session_id = None
self.multion = MultiOn(api_key=api_key or os.getenv("MULTION_API_KEY"))
def _run(
self,
cmd: str,
*args: Any,
**kwargs: Any,
) -> str:
"""Run the Multion client with the given command.
Args:
cmd (str): The detailed and specific natural language instructrion for web browsing
*args (Any): Additional arguments to pass to the Multion client
**kwargs (Any): Additional keyword arguments to pass to the Multion client
"""
if self.multion is None:
raise ValueError("Multion client is not initialized.")
browse = self.multion.browse(
cmd=cmd,
session_id=self.session_id,
local=self.local,
max_steps=self.max_steps,
*args, # noqa: B026
**kwargs,
)
self.session_id = browse.session_id
return str(browse.message) + "\n\n STATUS: " + str(browse.status)
View on GitHub (pinned to 754d7323be)
Solutions
- Re-instantiate MultiOnTool() instead of reconstructing/deserializing it
- After any serialization round-trip, reattach: tool.multion = MultiOn(api_key=os.getenv('MULTION_API_KEY'))
- In distributed workers, construct the tool inside the worker process, not in the parent
Example fix
# before
import pickle
tool = pickle.loads(pickle.dumps(MultiOnTool())) # client lost
tool._run(cmd="open example.com") # ValueError
# after
def make_tool():
return MultiOnTool() # construct in the worker process
# worker:
tool = make_tool()
tool._run(cmd="open example.com") Defensive patterns
Strategy: validation
Validate before calling
def multion_client_ready(tool) -> bool:
return getattr(tool, "multion", None) is not None Try / catch
try:
out = tool._run(cmd="open example.com")
except ValueError as e:
if "not initialized" in str(e):
from multion.client import MultiOn
import os
tool.multion = MultiOn(api_key=os.getenv("MULTION_API_KEY"))
out = tool._run(cmd="open example.com")
else:
raise Prevention
- Construct MultiOnTool inside the worker process, never pickle it
- After deserialization, reattach a fresh MultiOn client
- Health-check tool clients before starting a crew run
When it happens
Trigger: Setting tool.multion = None manually; creating the pydantic model without running __init__ (model_construct / dict round-trip); pickling/deep-copying the tool so the client reference is dropped; a failed constructor path that leaves multion unset.
Common situations: Passing tools between processes (Celery, multiprocessing) where the non-picklable client becomes None; rebuilding tools from cached config; test fixtures constructing the model directly.
Related errors
- Client is not initialized
- Failed to initialize MCP Adapter: {e}
- `multion` package not found, please run `uv add multion`
- Invalid data_type: '{raw_data_type}'. Valid values are: 'fil
- File does not exist: {source_ref}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/342d88b7f95d34e1.
Report an issue: GitHub.