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

  1. Re-instantiate MultiOnTool() instead of reconstructing/deserializing it
  2. After any serialization round-trip, reattach: tool.multion = MultiOn(api_key=os.getenv('MULTION_API_KEY'))
  3. 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

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


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/342d88b7f95d34e1. Report an issue: GitHub.