{"record":{"id":"42f211f60dc53932","repo":"zeroclaw-labs/zeroclaw","slug":"memory-write-denied-by-policy-error","errorCode":null,"errorMessage":"memory write denied by policy: {error}","messagePattern":"memory write denied by policy: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-memory/src/scanned.rs","lineNumber":244,"sourceCode":"        category: &MemoryCategory,\n    ) -> anyhow::Result<()> {\n        let namespace = namespace.unwrap_or(\"default\");\n        let enforcer = PolicyEnforcer::new(&self.policy);\n        if let Err(error) =\n            crate::policy_gate::validate_store(&self.inner, &enforcer, namespace, category).await\n        {\n            ::zeroclaw_log::record!(\n                WARN,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                    .with_attrs(::serde_json::json!({\n                        \"key\": key,\n                        \"namespace\": namespace,\n                        \"error\": error.to_string(),\n                    })),\n                \"memory write denied by policy\"\n            );\n            anyhow::bail!(\"memory write denied by policy: {error}\");\n        }\n        Ok(())\n    }\n\n    /// Re-scan one recalled entry; `true` means the entry passes.\n    fn entry_passes_read_scan(&self, entry: &MemoryEntry, scope: Scope) -> bool {\n        let findings = threat::scan(&entry.content, scope);\n        if findings.is_empty() {\n            return true;\n        }\n        let kinds = findings\n            .iter()\n            .map(|finding| finding.kind.to_string())\n            .collect::<Vec<_>>()\n            .join(\",\");\n        ::zeroclaw_log::record!(\n            WARN,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-memory/src/scanned.rs#L226-L262","documentation":"After content screening, enforce_policy() runs policy_gate::validate_store with a PolicyEnforcer built from [memory.policy] (namespace/category rules). Any violation aborts the write; the inner {error} text names the exact rule that failed. Fail-closed by design — every store* variant routes through this check.","triggerScenarios":"Storing into a namespace or category that [memory.policy] disallows (allow/deny rules, per-namespace limits such as max entries); all store, store_with_metadata, store_with_options and store_with_agent calls are gated.","commonSituations":"Tightening policy in config and forgetting call sites that write to now-restricted namespaces; new categories missing from the policy allowlist; bulk imports tripping per-namespace quotas.","solutions":["Read the inner error text — it names the violated rule (disallowed namespace, disallowed category, or a limit)","Write to a namespace/category permitted by [memory.policy], or extend the policy rules","If a per-namespace limit tripped, forget old entries or raise the limit","Restart after policy edits so ScannedMemory picks up the new policy"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Mirror [memory.policy] rules at the call site: refuse locally before the doomed write\nfn policy_allows(policy: &MemoryPolicyConfig, namespace: &str, category: &MemoryCategory) -> bool {\n    // replicate the namespace/category allow rules and limits you configured\n    true\n}\nanyhow::ensure!(policy_allows(&cfg.memory.policy, ns, &cat), \"write to {ns} will be denied by policy\");","typeGuard":"fn is_policy_denied(e: &anyhow::Error) -> bool {\n    e.to_string().starts_with(\"memory write denied by policy\")\n}","tryCatchPattern":"match memory.store(k, v).await {\n    Err(e) if is_policy_denied(&e) => { notify_owner_of_rule(&e); Ok(()) } // the inner text names the violated rule\n    other => other,\n}","preventionTips":["Keep [memory.policy] namespace/category rules in sync with every writing call site","Surface the inner rule text to users so they can self-correct the namespace","Watch per-namespace limits during bulk imports","Restart after policy edits; the decorator clones policy at construction"],"tags":["policy","authorization","namespaces","write-path","rust"],"backgroundTag":"policy-denied","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}