langchain-ai/deepagents · error · ValueError
exposure mode 'open' allows arbitrary senders to trigger…
Error message
{config.provider} exposure mode 'open' allows arbitrary senders to trigger the agent with operator credentials and local host access; set {config.open_ack}={config.open_ack_value} to acknowledge this risk What it means
Talon refuses to run a channel in 'open' exposure mode unless the operator explicitly acknowledges the risk. In open mode, anyone who can message the channel (e.g. any Telegram user) can trigger the agent, which executes with the operator's credentials and local host access. The check in `_require_open_acknowledgement` raises `ValueError` until the designated acknowledgement env var is set to its required value.
Solutions
- Read the error text: it names the exact env var (`config.open_ack`) and required value (`config.open_ack_value`) — set that variable to that value to acknowledge the risk.
- If you do not need public exposure, switch the exposure mode to a restricted mode (e.g. allowlist specific senders) instead of acknowledging open mode.
- If exposure=open was set accidentally (e.g. inherited env var), unset or correct DEEPAGENTS_TALON_EXPOSURE.
Example fix
// before DEEPAGENTS_TALON_EXPOSURE=open // after DEEPAGENTS_TALON_EXPOSURE=open DEEPAGENTS_TALON_OPEN_ACKNOWLEDGED=true # exact var/value per config.open_ack / config.open_ack_value
Defensive patterns
Strategy: validation
Validate before calling
import os
def is_open_exposure_acknowledged(ack_var: str, ack_value: str) -> bool:
return os.environ.get(ack_var) == ack_value
# refuse to start the channel unless acknowledged Type guard
def open_mode_acknowledged(env: dict[str, str], ack_var: str, ack_value: str) -> bool:
return env.get(ack_var) == ack_value Try / catch
try:
exposure = channel_exposure_from_env(env)
except ValueError as exc:
logging.error("channel startup refused: %s", exc)
raise SystemExit(2) Prevention
- Treat exposure=open as a production-security decision requiring review, not a default
- Store the acknowledgement var alongside the exposure var in your env template so they ship together
- Prefer restricted/allowlist exposure modes unless public triggering is intentional
- Add a startup smoke test in CI that catches unacknowledged open mode
When it happens
Trigger: Calling `channel_exposure_from_env` when the exposure mode resolves to 'open' (e.g. DEEPAGENTS_TALON_EXPOSURE=open) while the acknowledgement variable `config.open_ack` is missing or not equal to `config.open_ack_value`.
Common situations: Developers exposing a Telegram channel publicly for demos or quick tests forget the acknowledgement flag; CI or container environments set exposure=open via env vars without the ack; teams inherit configs from examples that used a restricted mode and switch to open without reviewing the security warning.
Related errors
- allow_fs_tools must be None or a non-empty list
- assistant id is required
- Cannot determine whether
- Could not apply to model profile
- interpreter_ptc='all' exposes every host tool to PTC calls…
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/98e77d25072a77ee.
Report an issue: GitHub.
Appendix: source
Thrown at libs/talon/deepagents_talon/channels/base.py:470
return ExposureMode(value)
except ValueError as error:
modes = ", ".join(mode.value for mode in ExposureMode)
msg = f"invalid {provider} exposure mode {value!r}; expected one of: {modes}"
raise ValueError(msg) from error
def _require_open_acknowledgement(
env: Mapping[str, str],
config: ChannelExposureEnv,
) -> None:
if env.get(config.open_ack) == config.open_ack_value:
return
msg = (
f"{config.provider} exposure mode 'open' allows arbitrary senders to trigger the "
"agent with operator credentials and local host access; set "
f"{config.open_ack}={config.open_ack_value} to acknowledge this risk"
)
raise ValueError(msg)
def _split_index(text: str, limit: int) -> int:
window = text[:limit]
for delimiter in ("\n\n", "\n", " "):
index = window.rfind(delimiter)
if index > 0:
return index + len(delimiter)
return limit
def _media_type(path: Path) -> str:
mime, _ = mimetypes.guess_type(path)
if mime is None:
msg = f"unsupported media file type: {path}"
raise ChannelMediaError(msg)
if mime.startswith("image/"):
return "image"View on GitHub (pinned to a1af029e6e)