tinyhumansai/openhuman · error

[meetings::store] set_event_policy: unknown policy {:?} (val

Error message

[meetings::store] set_event_policy: unknown policy {:?} (valid: auto, ask, skip)

What it means

set_event_policy persists per-calendar-event join-policy overrides into the meeting_event_policies table and deliberately validates the value before writing: anything outside the literal set auto | ask | skip is rejected so the table cannot accumulate invalid rows. This is pure input validation — nothing is written when it fires.

Source

Thrown at src/openhuman/meet/backend_bot/store.rs:256

/// Flag that a summary was generated for this session.
pub fn mark_summary_generated(config: &Config, id: &str, now_ms: u64) -> Result<()> {
    with_connection(config, |conn| {
        conn.execute(
            "UPDATE meeting_sessions SET summary_generated = 1, updated_at_ms = ?1 WHERE id = ?2",
            params![now_ms as i64, id],
        )?;
        Ok(())
    })
}

/// Persist or replace the join-policy override for a specific calendar event.
///
/// The `policy` must be one of "auto" | "ask" | "skip" — anything else is
/// rejected with an error so the table cannot accumulate invalid values.
pub fn set_event_policy(config: &Config, calendar_event_id: &str, policy: &str) -> Result<()> {
    if !matches!(policy, "auto" | "ask" | "skip") {
        anyhow::bail!(
            "[meetings::store] set_event_policy: unknown policy {:?} (valid: auto, ask, skip)",
            policy
        );
    }
    with_connection(config, |conn| {
        let now_ms = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap_or_default()
            .as_millis() as i64;
        conn.execute(
            "INSERT OR REPLACE INTO meeting_event_policies (calendar_event_id, policy, updated_at_ms) VALUES (?1, ?2, ?3)",
            rusqlite::params![calendar_event_id, policy, now_ms],
        )?;
        Ok(())
    })
}

/// Retrieve the join-policy override for a specific calendar event. Returns

View on GitHub (pinned to 7491200858)

Solutions

  1. Send exactly one of "auto", "ask", "skip" (lowercase).
  2. Map user-facing vocabulary at the edge (always→auto, never→skip) before calling the store.
  3. Confirm the accepted set for your version in the store's validator before adding new UI options.

Example fix

// before
store::set_event_policy(&config, "evt_123", "always")?; // rejected: unknown policy

// after — the accepted vocabulary
store::set_event_policy(&config, "evt_123", "auto")?;   // auto | ask | skip
Defensive patterns

Strategy: validation

Validate before calling

const EVENT_POLICIES: &[&str] = &["auto", "ask", "skip"];
if !EVENT_POLICIES.contains(&policy.trim()) {
    anyhow::bail!("policy must be one of {EVENT_POLICIES:?}, got {:?}", policy);
}

Type guard

fn is_valid_event_policy(p: &str) -> bool {
    matches!(p, "auto" | "ask" | "skip")
}

Try / catch

Catch the bail and re-surface it as an inline form error next to the policy selector — nothing was written, so the fix is purely client-side.

Prevention

When it happens

Trigger: Calling set_event_policy (or the RPC/agent surface that wraps it) with values like "always", "never", "yes", an empty string, or a capitalized form such as "Ask" — the vocabulary is lowercase and closed.

Common situations: UI dropdown out of sync with the accepted set; hand-crafted RPC calls guessing the enum; LLM-driven agents inventing values; newer client vocabulary against an older accepted set.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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