Local managed-settings allowedChannelPlugins silently discarded when remote org settings omit the key (still on 2.1.234; variant of #79290)
Summary
When remote (claude.ai org) managed settings exist but do not contain allowedChannelPlugins, the allowedChannelPlugins set in local managed settings (C:\Program Files\ClaudeCode\managed-settings.json / C:\ProgramData\ClaudeCode\managed-settings.json on Windows) is silently discarded. The channel allowlist then falls back to the default Anthropic list, so --channels and the channel_enable control request are refused for an org-approved plugin — while channelsEnabled: true from the same policy chain is honored, which makes the failure very hard to diagnose.
This is the same shadowing mechanism reported in #79290 (closed as completed 2026-07-20), still reproducing on 2.1.234. The variant here adds a twist: when the remote settings lack the key entirely, the skip message is the non-org one ("use --dangerously-load-development-channels for local dev"), so the admin isn't even pointed at managed settings any more.
Environment
- Claude Code 2.1.212 and 2.1.234 (bundled with Windows desktop app 1.32885), Windows 11
- Account: claude.ai org plan; remote managed settings cached at
~/.claude/remote-settings.jsoncontain exactly{"channelsEnabled": true} - Local managed settings (identical in both Windows locations, no HKLM/HKCU policy keys):
{
"channelsEnabled": true,
"allowedChannelPlugins": [
{ "marketplace": "local-desktop-app-uploads", "plugin": "friday-channel" }
]
}
- Plugin installed and connected; declares
capabilities.experimental['claude/channel']; negotiates legacy protocol era. NTFS last-access times confirm both local managed-settings files are read at session start.
Repro
- With the above policy state, launch headless:
claude -p --input-format stream-json --output-format stream-json --verbose. - Send
{"type":"control_request","request_id":"chan-1","request":{"subtype":"channel_enable","serverName":"plugin:friday-channel:friday-channel"}}. - Response:
{"type":"control_response","response":{"subtype":"error","request_id":"chan-1","error":"plugin friday-channel@local-desktop-app-uploads is not on the approved channels allowlist (use --dangerously-load-development-channels for local dev)"}}
claude --channels plugin:friday-channel@local-desktop-app-uploads is refused the same way. Note the policy stage passed (enterprise-type accounts require channelsEnabled === true, and it was honored), so the merged policy object demonstrably carried channelsEnabled from the chain — only allowedChannelPlugins was lost.
Expected
Local managed settings (admin-controlled, machine-scoped) should merge with — or at minimum not be silently discarded by — remote org settings that don't define the key. If replacement is intentional, the skip message should say the local file was shadowed by remote org settings rather than suggesting a dev flag.
Impact
Any org that flips channelsEnabled: true in the claude.ai admin console without also (or without being able to) set allowedChannelPlugins there strands every machine-local allowlist, leaving the dev flag (interactive-only, per-launch dialog) as the sole path to run an internal channel plugin.