{"record":{"id":"d2e6515c45183738","repo":"langchain-ai/deepagents","slug":"output-as-app-message-requires-incognito-true-ref","errorCode":null,"errorMessage":"output_as_app_message requires incognito=True; refusing to buffer app-rendered shell output for the model","messagePattern":"output_as_app_message requires incognito=True; refusing to buffer app-rendered shell output for the model","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/app.py","lineNumber":12334,"sourceCode":"                is identical either way.\n            output_as_app_message: Render output as an `AppMessage` status note\n                instead of a local-only `AssistantMessage`. Exists for\n                `--startup-cmd`, whose output is setup noise the user did not\n                type; it governs only the success-output branch, not the\n                timeout, nonzero-exit, or no-output messages. Requires\n                `incognito` — app-style output would otherwise read as local\n                setup noise while still being buffered for the model.\n\n        Raises:\n            CancelledError: If the command is interrupted by the user.\n            ValueError: If `output_as_app_message` is set without `incognito`.\n        \"\"\"\n        if output_as_app_message and not incognito:\n            msg = (\n                \"output_as_app_message requires incognito=True; refusing to \"\n                \"buffer app-rendered shell output for the model\"\n            )\n            raise ValueError(msg)\n\n        refresh_started = False\n        try:\n            proc = await asyncio.create_subprocess_shell(\n                command,\n                stdout=asyncio.subprocess.PIPE,\n                stderr=asyncio.subprocess.PIPE,\n                cwd=self._cwd,\n                start_new_session=(sys.platform != \"win32\"),\n            )\n            self._shell_process = proc\n\n            try:\n                stdout_bytes, stderr_bytes = await asyncio.wait_for(\n                    proc.communicate(),\n                    timeout=60,\n                )\n            except TimeoutError:","sourceCodeStart":12316,"sourceCodeEnd":12352,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/app.py#L12316-L12352","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass incognito=True together with output_as_app_message=True","If you don't need app-rendered output, drop output_as_app_message and keep default buffering","Route UI-only output through the appropriate display path instead of the model-facing one"],"exampleFix":"// before\nawait run_shell(command, output_as_app_message=True)\n// after\nawait run_shell(command, output_as_app_message=True, incognito=True)","handlingStrategy":"validation","validationCode":"if output_as_app_message and not incognito:\n    raise ValueError(\"output_as_app_message requires incognito=True\")","typeGuard":"def is_valid_shell_flags(output_as_app_message: bool, incognito: bool) -> bool:\n    return not output_as_app_message or incognito","tryCatchPattern":"try:\n    result = await run_shell(cmd, output_as_app_message=True, incognito=True)\nexcept ValueError as exc:\n    logger.error(\"shell flag misuse: %s\", exc)","preventionTips":["Treat output_as_app_message and incognito as one combined flag pair","Centralize shell invocation in one helper that sets both flags together","Read the buffering contract before wiring custom tool paths"],"tags":["shell","flag-combination","argument-validation"],"backgroundTag":"incompatible-flag-combination","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}