langchain-ai/deepagents · error · ValueError

output_as_app_message requires incognito=True; refusing to b

Error message

output_as_app_message requires incognito=True; refusing to buffer app-rendered shell output for the model

What it means

The shell-tool runner buffers command output for the model only when running incognito (not app-rendered). Requesting `output_as_app_message=True` without `incognito=True` would feed UI-rendered shell output to the model, which is explicitly refused, so a ValueError is raised before spawning the subprocess.

Source

Thrown at libs/code/deepagents_code/app.py:12334

                is identical either way.
            output_as_app_message: Render output as an `AppMessage` status note
                instead of a local-only `AssistantMessage`. Exists for
                `--startup-cmd`, whose output is setup noise the user did not
                type; it governs only the success-output branch, not the
                timeout, nonzero-exit, or no-output messages. Requires
                `incognito` — app-style output would otherwise read as local
                setup noise while still being buffered for the model.

        Raises:
            CancelledError: If the command is interrupted by the user.
            ValueError: If `output_as_app_message` is set without `incognito`.
        """
        if output_as_app_message and not incognito:
            msg = (
                "output_as_app_message requires incognito=True; refusing to "
                "buffer app-rendered shell output for the model"
            )
            raise ValueError(msg)

        refresh_started = False
        try:
            proc = await asyncio.create_subprocess_shell(
                command,
                stdout=asyncio.subprocess.PIPE,
                stderr=asyncio.subprocess.PIPE,
                cwd=self._cwd,
                start_new_session=(sys.platform != "win32"),
            )
            self._shell_process = proc

            try:
                stdout_bytes, stderr_bytes = await asyncio.wait_for(
                    proc.communicate(),
                    timeout=60,
                )
            except TimeoutError:

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass incognito=True together with output_as_app_message=True
  2. If you don't need app-rendered output, drop output_as_app_message and keep default buffering
  3. Route UI-only output through the appropriate display path instead of the model-facing one

Example fix

// before
await run_shell(command, output_as_app_message=True)
// after
await run_shell(command, output_as_app_message=True, incognito=True)
Defensive patterns

Strategy: validation

Validate before calling

if output_as_app_message and not incognito:
    raise ValueError("output_as_app_message requires incognito=True")

Type guard

def is_valid_shell_flags(output_as_app_message: bool, incognito: bool) -> bool:
    return not output_as_app_message or incognito

Try / catch

try:
    result = await run_shell(cmd, output_as_app_message=True, incognito=True)
except ValueError as exc:
    logger.error("shell flag misuse: %s", exc)

Prevention

When it happens

Trigger: Calling the shell execution helper with `output_as_app_message=True` while leaving `incognito` at its default False — e.g. wiring a custom tool path that wants pretty output without realizing the buffering contract.

Common situations: Integrators extending the shell tool or porting call sites between the standard runner and the app-message variant; combining flags from two different invocation styles.

Related errors


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