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. ReturnsView on GitHub (pinned to 7491200858)
Solutions
- Send exactly one of "auto", "ask", "skip" (lowercase).
- Map user-facing vocabulary at the edge (always→auto, never→skip) before calling the store.
- 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
- Drive the UI dropdown from the same literal list the store validates.
- Validate before the RPC so users get immediate feedback.
- Trim and lowercase user/agent input at the boundary before it reaches the store.
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
- mascot manifest: missing mascots array
- mascot manifest: no renderable mascots
- audio blob is empty
- audio blob is empty
- Recovery phrase is required.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/7812710d71466a22.
Report an issue: GitHub.