zeroclaw-labs/zeroclaw · error

invalid memory.policy.threat_scan value {other:?}; expected

Error message

invalid memory.policy.threat_scan value {other:?}; expected off, on, or strict

What it means

ScannedMemory::scan_mode() parses [memory.policy].threat_scan: trimmed, lowercased, then matched against exactly off | on | strict; anything else bails. The value is parsed lazily inside store/recall paths, so a typo survives config load and detonates on the first scanned memory operation.

Source

Thrown at crates/zeroclaw-memory/src/scanned.rs:89

    fn alias(&self) -> &str {
        self.inner.alias()
    }
}

impl<M: Memory> ScannedMemory<M> {
    pub fn new(inner: M, policy: &MemoryPolicyConfig) -> Self {
        Self {
            inner,
            policy: policy.clone(),
        }
    }

    fn scan_mode(&self) -> anyhow::Result<ThreatScanMode> {
        match self.policy.threat_scan.trim().to_ascii_lowercase().as_str() {
            "off" => Ok(ThreatScanMode::Off),
            "on" => Ok(ThreatScanMode::On),
            "strict" => Ok(ThreatScanMode::Strict),
            other => anyhow::bail!(
                "invalid memory.policy.threat_scan value {other:?}; expected off, on, or strict"
            ),
        }
    }

    fn on_hit(&self) -> anyhow::Result<OnHit> {
        match self
            .policy
            .threat_scan_on_hit
            .trim()
            .to_ascii_lowercase()
            .as_str()
        {
            "reject" => Ok(OnHit::Reject),
            "block-on-read" | "block_on_read" => Ok(OnHit::BlockOnRead),
            other => anyhow::bail!(
                "invalid memory.policy.threat_scan_on_hit value {other:?}; expected reject or block-on-read"
            ),

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set threat_scan to exactly one of: off, on, strict
  2. Restart the agent after editing [memory.policy]
  3. Confirm the effective value via the loaded-config view before the first write
  4. Add a startup validation pass over enum-like policy fields

Example fix

# before
[memory.policy]
threat_scan = "enabled"

# after
[memory.policy]
threat_scan = "on"   # off | on | strict
Defensive patterns

Strategy: validation

Validate before calling

const VALID: [&str; 3] = ["off", "on", "strict"];
let v = cfg.memory.policy.threat_scan.trim().to_ascii_lowercase();
anyhow::ensure!(VALID.contains(&v.as_str()), "threat_scan must be off|on|strict, got {v}");

Type guard

fn is_valid_threat_scan(v: &str) -> bool {
    matches!(v.trim().to_ascii_lowercase().as_str(), "off" | "on" | "strict")
}

Try / catch

if let Err(e) = memory.store(k, v).await {
    if e.to_string().contains("invalid memory.policy.threat_scan value") { fix_config_and_restart(); }
    return Err(e);
}

Prevention

When it happens

Trigger: Setting threat_scan = "enabled", "true", "false", or "strict mode" in zeroclaw.toml; case is fine ("Strict" works because of lowercasing) but extra words and punctuation are not.

Common situations: Copy-pasted config snippets from other zeroclaw versions; booleans where the enum is expected; docs drift on policy field values.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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