crewAIInc/crewAI · error · RuntimeError

FirecrawlApp not properly initialized

Error message

FirecrawlApp not properly initialized

What it means

RuntimeError raised at the top of FirecrawlSearchTool._run when self._firecrawl is falsy, i.e. the FirecrawlApp client was never attached. As with the sibling Firecrawl tools, the constructor sets it on every success path, so this guard trips only for objects that skipped or partially completed __init__.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/firecrawl_search_tool/firecrawl_search_tool.py:111

                try:
                    subprocess.run(["uv", "add", "firecrawl-py"], check=True)  # noqa: S607
                    from firecrawl import FirecrawlApp

                    self._firecrawl = FirecrawlApp(api_key=self.api_key)
                except subprocess.CalledProcessError as e:
                    raise ImportError("Failed to install firecrawl-py package") from e
            else:
                raise ImportError(
                    "`firecrawl-py` package not found, please run `uv add firecrawl-py`"
                ) from None

    def _run(
        self,
        query: str,
    ) -> Any:
        if not self._firecrawl:
            raise RuntimeError("FirecrawlApp not properly initialized")

        return self._firecrawl.search(
            query=query,
            **self.config,
        )


try:
    from firecrawl import FirecrawlApp  # noqa: F401

    if not getattr(FirecrawlSearchTool, "_model_rebuilt", False):
        FirecrawlSearchTool.model_rebuild()
        FirecrawlSearchTool._model_rebuilt = True  # type: ignore[attr-defined]
except ImportError:
    pass

View on GitHub (pinned to 754d7323be)

Solutions

  1. Use the normal constructor: FirecrawlSearchTool(api_key=...).
  2. For tests, assign tool._firecrawl = MagicMock() before calling _run.
  3. Never reuse an instance whose __init__ raised.

Example fix

# before
tool = FirecrawlSearchTool.__new__(FirecrawlSearchTool)
tool._run('query')  # RuntimeError

# after
tool = FirecrawlSearchTool(api_key=FIRECRAWL_API_KEY)
tool._run('query')
Defensive patterns

Strategy: type-guard

Validate before calling

if not getattr(tool, '_firecrawl', None):
    raise RuntimeError('search tool has no FirecrawlApp client')

Type guard

def search_tool_ready(tool) -> bool:
    return bool(getattr(tool, '_firecrawl', None))

Try / catch

try:
    out = tool._run(query)
except RuntimeError as e:
    if 'not properly initialized' in str(e):
        tool = FirecrawlSearchTool(api_key=KEY)
        out = tool._run(query)
    else:
        raise

Prevention

When it happens

Trigger: Invoking _run(query) on an instance produced by __new__, model_copy, or a mock whose _firecrawl attribute is unset/None.

Common situations: Test harnesses mocking the tool but forgetting the client attribute; init exceptions swallowed by broad excepts leaving a zombie instance.

Related errors


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