tinyhumansai/openhuman · error

allowlist persist unsupported for channel '{other}'

Error message

allowlist persist unsupported for channel '{other}'

What it means

`persist_allowed_identity` implements exactly one channel arm — `"telegram"`. Every other channel name falls into the `other` wildcard arm and bails with `allowlist persist unsupported for channel '{other}'`. This is a deliberate capability gap: no provider other than Telegram has on-disk allowlist persistence to config.toml via this store yet.

Source

Thrown at src/openhuman/channels/host/adapters.rs:313

        let mut config: Config =
            toml::from_str(&contents).context("failed to parse config.toml for allowlist")?;
        config.config_path = config_path;
        config.workspace_dir = openhuman_dir.join("workspace");

        match channel {
            "telegram" => {
                let Some(telegram) = config.channels_config.telegram.as_mut() else {
                    anyhow::bail!("telegram channel config is missing in config.toml");
                };
                if !telegram.allowed_users.iter().any(|u| u == &normalized) {
                    telegram.allowed_users.push(normalized);
                    config
                        .save()
                        .await
                        .context("failed to persist allowlist to config.toml")?;
                }
            }
            other => anyhow::bail!("allowlist persist unsupported for channel '{other}'"),
        }
        tracing::debug!("{LOG_PREFIX} persisted allowed identity for channel={channel}");
        Ok(())
    }
}

// ---------------------------------------------------------------------------
// EventSink → routes provider events to the right OpenHuman bus
// ---------------------------------------------------------------------------

/// Routes provider events by `domain`:
/// - `"web"`     → the web channel's `WebChannelEvent` broadcast bus (payload
///   must deserialize into a `WebChannelEvent`; presentation builds that shape).
/// - `"channel"` → the global `DomainEvent` bus (telegram reaction fan-out).
///
/// One capability, two backends — providers don't know which bus they hit.
pub struct OpenHumanEventSink;

View on GitHub (pinned to 7491200858)

Solutions

  1. Add a match arm for the channel mirroring the telegram arm (mutate that provider's config field, e.g. `config.channels_config.<provider>.allowed_users`, and save).
  2. If the channel does not need on-disk allowlist persistence, gate the persist call at the call site so only telegram reaches the store.
  3. Check the channel string matches the arm exactly — lowercase `"telegram"`.

Example fix

// before
match channel {
    "telegram" => { /* ... */ }
    other => anyhow::bail!("allowlist persist unsupported for channel '{other}'"),
}

// after — implement the new provider's arm
match channel {
    "telegram" => { /* ... */ }
    "discord" => {
        let Some(discord) = config.channels_config.discord.as_mut() else {
            anyhow::bail!("discord channel config is missing in config.toml");
        };
        if !discord.allowed_users.iter().any(|u| u == &normalized) {
            discord.allowed_users.push(normalized);
            config.save().await.context("failed to persist allowlist to config.toml")?;
        }
    }
    other => anyhow::bail!("allowlist persist unsupported for channel '{other}'"),
}
Defensive patterns

Strategy: type-guard

Validate before calling

if supports_config_allowlist_persist(channel) {
    store.persist_allowed_identity(channel, identity).await?;
} // else: this channel has no on-disk allowlist persistence — skip silently

Type guard

fn supports_config_allowlist_persist(channel: &str) -> bool {
    matches!(channel, "telegram")
}

Try / catch

match store.persist_allowed_identity(channel, identity).await {
    Err(e) if e.to_string().starts_with("allowlist persist unsupported") => {
        // capability gap, not a failure — skip persistence for this channel
    }
    other => other?,
}

Prevention

When it happens

Trigger: A channel adapter for any non-telegram provider (discord, whatsapp, slack, signal, …) is wired to `ConfigAllowlistStore` and calls `persist_allowed_identity` with its channel name; also a misspelled or differently-cased channel key (e.g. "Telegram", "tg") that no longer matches the one implemented arm.

Common situations: Adding a new channel provider to the host and reusing the shared allowlist store; refactors that rename channel identifier strings; integrations that assume feature parity across channels.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/c7801c74cb15429d. Report an issue: GitHub.