langchain-ai/langchain · error · RuntimeError

File is not open. Use FileCallbackHandler as a context manag

Error message

File is not open. Use FileCallbackHandler as a context manager.

What it means

`FileCallbackHandler.on_text` (langchain_core/callbacks/file.py) raises `RuntimeError('File is not open...')` when the handler's underlying file is missing or closed — i.e. the handler was used without its context manager, so `__enter__` never opened `self.file`. The check fires before every `print_text` call.

Source

Thrown at libs/core/langchain_core/callbacks/file.py:159

            RuntimeError: If the file is closed or not available.

        """
        global _GLOBAL_DEPRECATION_WARNED  # noqa: PLW0603
        if not self._file_opened_in_context and not _GLOBAL_DEPRECATION_WARNED:
            warn_deprecated(
                since="0.3.67",
                pending=True,
                message=(
                    "Using FileCallbackHandler without a context manager is "
                    "deprecated. Use 'with FileCallbackHandler(...) as "
                    "handler:' instead."
                ),
            )
            _GLOBAL_DEPRECATION_WARNED = True

        if not hasattr(self, "file") or self.file is None or self.file.closed:
            msg = "File is not open. Use FileCallbackHandler as a context manager."
            raise RuntimeError(msg)

        print_text(text, file=self.file, color=color, end=end)

    @override
    def on_chain_start(
        self, serialized: dict[str, Any], inputs: dict[str, Any], **kwargs: Any
    ) -> None:
        """Print that we are entering a chain.

        Args:
            serialized: The serialized chain information.
            inputs: The inputs to the chain.
            **kwargs: Additional keyword arguments that may contain `'name'`.

        """
        name = (
            kwargs.get("name")
            or serialized.get("name", serialized.get("id", ["<unknown>"])[-1])

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Use the handler as a context manager: `with FileCallbackHandler(path) as handler: chain.invoke(..., config={'callbacks': [handler]})`
  2. Create a fresh handler instance per run/session instead of reusing one after its `with` block exited
  3. Ensure the `with` block encloses every invoke/agent run that references the handler
  4. Suppress lint pressure to inline the constructor: keep the `with` even when the body is just the invoke call

Example fix

# before
handler = FileCallbackHandler(file_path="log.txt")
chain.invoke(inputs, config={"callbacks": [handler]})

# after
with FileCallbackHandler(file_path="log.txt") as handler:
    chain.invoke(inputs, config={"callbacks": [handler]})
Defensive patterns

Strategy: validation

Validate before calling

def handler_is_usable(handler) -> bool:
    return getattr(getattr(handler, 'file', None), 'closed', True) is False

# prefer structural prevention: always use `with`

Prevention

When it happens

Trigger: Creating `FileCallbackHandler(file_path=...)` and passing it to a chain/agent without wrapping it in `with`, then any callback event that prints text triggers the error; also using the same handler instance after the `with` block has exited and closed the file.

Common situations: Migrating old code that constructed the handler directly; registering the handler globally (e.g. via `callbacks=[handler]`) while forgetting the `with` statement; reusing a handler across sessions after file close. The deprecation warning at the top of the region flags exactly this pattern.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/e83894b94383edea. Report an issue: GitHub.