{"record":{"id":"5015854e8d6ab195","repo":"langchain-ai/deepagents","slug":"invalid-provider-exposure-mode-value-r-expect","errorCode":null,"errorMessage":"invalid {provider} exposure mode {value!r}; expected one of: {modes}","messagePattern":"invalid (.+?) exposure mode (.+?); expected one of: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/talon/deepagents_talon/channels/base.py","lineNumber":456,"sourceCode":"\n\ndef _is_self_message(message: ChannelMessage, operator_ids: frozenset[str]) -> bool:\n    if message.metadata.get(\"from_self\") is True:\n        return True\n    return message.sender_id is not None and message.sender_id in operator_ids\n\n\ndef _matches_text(text: str, patterns: tuple[str, ...]) -> bool:\n    return any(fnmatch.fnmatchcase(text, pattern) for pattern in patterns)\n\n\ndef _exposure_mode(value: str, *, provider: str) -> ExposureMode:\n    try:\n        return ExposureMode(value)\n    except ValueError as error:\n        modes = \", \".join(mode.value for mode in ExposureMode)\n        msg = f\"invalid {provider} exposure mode {value!r}; expected one of: {modes}\"\n        raise ValueError(msg) from error\n\n\ndef _require_open_acknowledgement(\n    env: Mapping[str, str],\n    config: ChannelExposureEnv,\n) -> None:\n    if env.get(config.open_ack) == config.open_ack_value:\n        return\n    msg = (\n        f\"{config.provider} exposure mode 'open' allows arbitrary senders to trigger the \"\n        \"agent with operator credentials and local host access; set \"\n        f\"{config.open_ack}={config.open_ack_value} to acknowledge this risk\"\n    )\n    raise ValueError(msg)\n\n\ndef _split_index(text: str, limit: int) -> int:\n    window = text[:limit]","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/channels/base.py#L438-L474","documentation":"`_exposure_mode` converts the exposure env string into an `ExposureMode` via `ExposureMode(value)`; valid values are `self`, `allowlist`, and `open`. An unknown string raises a ValueError listing the provider name, the bad value, and all accepted modes.","triggerScenarios":"Setting `<PREFIX>_EXPOSURE` (e.g. `DEEPAGENTS_TALON_TELEGRAM_EXPOSURE`) to anything other than `self`/`allowlist`/`open` — e.g. `public`, `whitelist`, `Open` (case matters beyond exact match), `restricted` — then calling `channel_exposure_from_env` from `from_talon_config`.","commonSituations":"Typo'd or older mode names from previous versions (`whitelist` vs `allowlist`); capitalized values from YAML-exported env; copying config between providers with different modes.","solutions":["Set the var to one of the listed modes exactly: `self`, `allowlist`, or `open`.","Use lowercase values; the enum is case-sensitive.","Catch the ValueError at startup — the message enumerates valid modes for the given provider."],"exampleFix":"# before\nDEEPAGENTS_TALON_TELEGRAM_EXPOSURE=whitelist\n\n# after\nDEEPAGENTS_TALON_TELEGRAM_EXPOSURE=allowlist","handlingStrategy":"validation","validationCode":"import os\nvalid = {'self', 'allowlist', 'open'}\nraw = os.environ.get('DEEPAGENTS_TALON_TELEGRAM_EXPOSURE', 'self')\nif raw not in valid:\n    raise SystemExit(f'{raw!r} is not a valid exposure mode; expected one of: ' + ', '.join(sorted(valid)))","typeGuard":null,"tryCatchPattern":"try:\n    exposure = channel_exposure_from_env(os.environ, config)\nexcept ValueError as exc:\n    raise SystemExit(f'invalid exposure config: {exc}') from exc","preventionTips":["Only use the exact lowercase mode strings self/allowlist/open.","Grep deployment configs for old mode names like `whitelist` or `public`.","Render exposure mode from an enum in tooling instead of free-text strings."],"tags":["config","env","enum-validation"],"backgroundTag":"invalid-env-var-value","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}