zeroclaw-labs/zeroclaw · error
invalid memory.policy.redact_categories value(s): {}; expect
Error message
invalid memory.policy.redact_categories value(s): {}; expected secret, api_key, private_key, email, or phone What it means
When redact_on_write is enabled, redaction_categories() maps every entry of [memory.policy].redact_categories through RedactCategory::from_config; accepted values are secret, api_key, private_key, email, phone. All unknown entries are collected and reported together in one error listing the offenders.
Source
Thrown at crates/zeroclaw-memory/src/scanned.rs:137
/// Scope for read-time re-scanning; `None` disables read filtering.
fn read_scope(&self) -> anyhow::Result<Option<Scope>> {
if !self.policy.threat_scan_load_time {
return Ok(None);
}
self.scan_scope()
}
fn redaction_categories(&self) -> anyhow::Result<Vec<RedactCategory>> {
let mut parsed = Vec::with_capacity(self.policy.redact_categories.len());
let mut invalid = Vec::new();
for category in &self.policy.redact_categories {
match RedactCategory::from_config(category) {
Some(category) => parsed.push(category),
None => invalid.push(category.as_str()),
}
}
if !invalid.is_empty() {
anyhow::bail!(
"invalid memory.policy.redact_categories value(s): {}; expected secret, api_key, private_key, email, or phone",
invalid.join(",")
);
}
Ok(parsed)
}
/// Candidate count to request from the backend for a read-time filtered
/// recall of `limit` rows. See [`READ_REFILL_MULTIPLIER`] for the bound.
fn read_fetch_limit(limit: usize) -> usize {
if limit == 0 {
return 0;
}
limit.saturating_mul(READ_REFILL_MULTIPLIER).max(limit)
}
/// Run the write-boundary pipeline on one content payload: redact
/// configured categories (when `redact_on_write` is enabled), then scanView on GitHub (pinned to 88bb9c8533)
Solutions
- Rename or remove invalid entries so only the five supported categories remain
- Leave redact_categories empty (with redact_on_write still true) to disable category redaction without touching the flag
- Restart after editing and test with a single store call
- Validate the list at startup when redaction is enabled
Example fix
# before [memory.policy] redact_on_write = true redact_categories = ["phone_number", "emails"] # after [memory.policy] redact_on_write = true redact_categories = ["phone", "email"] # secret | api_key | private_key | email | phone
Defensive patterns
Strategy: validation
Validate before calling
const VALID: [&str; 5] = ["secret", "api_key", "private_key", "email", "phone"];
for c in &cfg.memory.policy.redact_categories {
anyhow::ensure!(VALID.contains(&c.trim().to_ascii_lowercase().as_str()), "invalid redact category {c}");
} Type guard
fn is_valid_redact_category(v: &str) -> bool {
matches!(v, "secret" | "api_key" | "private_key" | "email" | "phone")
} Try / catch
if let Err(e) = memory.store(k, v).await {
if e.to_string().contains("invalid memory.policy.redact_categories value") { fix_config_and_restart(); }
return Err(e);
} Prevention
- Validate categories whenever redact_on_write is enabled
- Empty list is valid and disables category redaction
- Keep category names sourced from the docs table
When it happens
Trigger: redact_on_write = true together with category names like phone_number, credit_card, credentials, or email_address; parsing happens on the write path, so it fails on the first store after enabling redaction.
Common situations: Renamed categories across zeroclaw versions; guessed category names; template configs left with placeholder entries.
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
- invalid memory.policy.threat_scan value {other:?}; expected
- invalid memory.policy.threat_scan_on_hit value {other:?}; ex
- cloud_ops.iac_tools must not be empty when cloud_ops is enab
- gateway.path_prefix contains invalid character '{bad}'; only
- risk_profiles.{profile_alias}.shell_env_passthrough[{i}] is
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/e2e5ebdcc40aad7d.
Report an issue: GitHub.