langchain-ai/deepagents · error · TypeError

stream_output_is_visible must be a bool, got {type(stream_ou

Error message

stream_output_is_visible must be a bool, got {type(stream_output_is_visible).__name__}

What it means

The constructor validates that `stream_output_is_visible` is strictly a `bool`. Passing any other type (int, string, None) raises a `TypeError` naming the received type, so stream visibility can never be truthiness-inferred.

Source

Thrown at libs/code/deepagents_code/model_retry.py:1076

        Raises:
            TypeError: If `max_retries` or `stream_output_is_visible` has the
                wrong type.
            ValueError: If `max_retries` is negative.
        """
        # `True >= 0` passes and `range(True + 1)` runs two attempts, so an
        # unchecked bool reads as a budget of one retry.
        if isinstance(max_retries, bool):
            msg = f"max_retries must be an int, got {type(max_retries).__name__}"
            raise TypeError(msg)
        if max_retries < 0:
            msg = "max_retries must be >= 0"
            raise ValueError(msg)
        if not isinstance(stream_output_is_visible, bool):
            msg = (
                "stream_output_is_visible must be a bool, got "
                f"{type(stream_output_is_visible).__name__}"
            )
            raise TypeError(msg)
        self.max_retries = max_retries
        self.stream_output_is_visible = stream_output_is_visible

    @staticmethod
    def _emit_stream_event(request: ModelRequest, event: dict[str, object]) -> None:
        writer = getattr(getattr(request, "runtime", None), "stream_writer", None)
        if writer is None:
            return
        try:
            writer(event)
        except GraphBubbleUp:
            # LangGraph control flow must not be mistaken for a writer fault.
            raise
        except Exception:
            # These events are the only signal that a pause is a retry and the
            # only correlation a client has between chunks and attempts, so
            # losing one must be visible in the logs without failing the run.
            logger.warning(

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass an explicit boolean: `stream_output_is_visible=True`
  2. Coerce at the config boundary with `bool(int(os.environ.get(...)))` or `value in ("1", "true")`
  3. Give Optional values an explicit boolean default before construction

Example fix

// before
RetryModel(inner, stream_output_is_visible=os.environ.get("STREAM_VISIBLE"))
// after
RetryModel(inner, stream_output_is_visible=os.environ.get("STREAM_VISIBLE", "1") == "1")
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(stream_output_is_visible, bool):
    raise TypeError(f"stream_output_is_visible must be bool, got {type(stream_output_is_visible).__name__}")

Type guard

def is_bool(v: object) -> TypeGuard[bool]:
    return isinstance(v, bool)

Try / catch

try:
    model = RetryModel(inner, stream_output_is_visible=flag)
except TypeError as e:
    logging.error("bad flag type: %s", e)
    model = RetryModel(inner, stream_output_is_visible=False)

Prevention

When it happens

Trigger: Passing `stream_output_is_visible=1`, `"yes"`, `None`, or a config value that was not converted to bool when constructing the retry model.

Common situations: Environment variables parsed as strings (`STREAM_VISIBLE="1"`) passed through unconverted; JSON configs with 0/1 or "true"/"false" strings; forwarding an Optional value without a default.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/72018bc6de92c232. Report an issue: GitHub.