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
- Use the handler as a context manager: `with FileCallbackHandler(path) as handler: chain.invoke(..., config={'callbacks': [handler]})`
- Create a fresh handler instance per run/session instead of reusing one after its `with` block exited
- Ensure the `with` block encloses every invoke/agent run that references the handler
- 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
- Always construct FileCallbackHandler inside a `with` statement in the same expression scope as the invoke call
- Create a new handler per run; never reuse after the context exits
- Treat the preceding deprecation warning as the real signal to fix usage
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
- A pending deprecation cannot have a scheduled removal
- Cannot specify both alternative and alternative_import
- alternative_import must be a fully qualified module path. Go
- Field {obj} must have a name to be deprecated.
- {f.__name__}() got multiple values for argument {new!r}
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/e83894b94383edea.
Report an issue: GitHub.