zeroclaw-labs/zeroclaw · error · anyhow::Error

matrix: configure either `access_token` or `password`

Error message

matrix: configure either `access_token` or `password`

What it means

The Matrix channel constructor validates that at least one authentication credential is present: a non-blank `access_token` or a non-blank `password`. Both values are trimmed before the check, so whitespace-only counts as missing. The constructor fails fast rather than starting a listener that could never authenticate to the homeserver.

Source

Thrown at crates/zeroclaw-channels/src/matrix.rs:3998

    pub fn new(
        config: MatrixConfig,
        alias: impl Into<String>,
        peer_resolver: Arc<dyn Fn() -> Vec<String> + Send + Sync>,
        state_dir: PathBuf,
    ) -> Result<Self> {
        if config.homeserver.trim().is_empty() {
            bail!("matrix: `homeserver` is required");
        }
        let has_token = config
            .access_token
            .as_deref()
            .is_some_and(|t| !t.trim().is_empty());
        let has_password = config
            .password
            .as_deref()
            .is_some_and(|p| !p.trim().is_empty());
        if !has_token && !has_password {
            bail!("matrix: configure either `access_token` or `password`");
        }
        let ack_reactions = config.ack_reactions.unwrap_or(true);
        let streaming_state = streaming::State::for_stream_mode(config.stream_mode);
        Ok(Self {
            config: Arc::new(config),
            alias: alias.into(),
            peer_resolver,
            state_dir,
            workspace_dir: None,
            transcription: None,
            client: tokio::sync::OnceCell::new(),
            pending_approvals: Arc::new(TokioMutex::new(HashMap::new())),
            streaming_state: Arc::new(TokioRwLock::new(streaming_state)),
            threads_seen: Arc::new(TokioRwLock::new(HashSet::new())),
            alias_cache: Arc::new(TokioRwLock::new(HashMap::new())),
            reaction_log: Arc::new(TokioMutex::new(HashMap::new())),
            bot_display_name: Arc::new(TokioRwLock::new(None)),
            initial_sync_done: Arc::new(AtomicBool::new(false)),

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set `access_token` in `[channels.matrix.<alias>]` to a valid Matrix access token
  2. Or set `password` (with the bot username) so the channel can perform password login
  3. Check the key spelling (`access_token`, not `accessToken`) and remove surrounding whitespace-only values
  4. If the token comes from an env var, confirm the variable is exported and correctly referenced

Example fix

# before
[channels.matrix.home]
homeserver_url = "https://matrix.org"
username = "@bot:matrix.org"

# after
[channels.matrix.home]
homeserver_url = "https://matrix.org"
username = "@bot:matrix.org"
access_token = "syt_..."   # or: password = "..."
Defensive patterns

Strategy: validation

Validate before calling

let m = &config.channels.matrix;
let has_auth = m
    .access_token
    .as_deref()
    .is_some_and(|t| !t.trim().is_empty())
    || m.password.as_deref().is_some_and(|p| !p.trim().is_empty());
if !has_auth {
    return Err(anyhow::anyhow!("matrix channel needs access_token or password"));
}

Prevention

When it happens

Trigger: Constructing a Matrix channel (startup, config load of `[channels.matrix.<alias>]`, or programmatic `new`) with `access_token` absent/blank AND `password` absent/blank.

Common situations: New Matrix setup where only homeserver_url and username are filled in; token expected from an env var that is not set or not expanded; TOML key typo like `accessToken`; secret line lost when editing config.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/450892d9a2d3be09. Report an issue: GitHub.