zeroclaw-labs/zeroclaw · error
{flag} = true requires memory.backend = "sqlite" (typed memo
Error message
{flag} = true requires memory.backend = "sqlite" (typed memory storage is SQLite-only), but memory.backend = {:?} What it means
Typed memory features (memory.types.enabled = true or memory.consolidation_extract_facts = true) persist typed rows in SQLite only. create_memory_for_agent refuses to construct the agent's memory when such a flag is set but the global memory.backend is not sqlite, rather than silently dropping typed data. The message interpolates the exact flag that tripped (memory.types.enabled or memory.consolidation_extract_facts).
Source
Thrown at crates/zeroclaw-memory/src/lib.rs:1007
let backend_kind = agent_cfg.memory.backend;
// Typed-memory producers are SQLite-only. Config::validate already
// rejects this combination on every save path, but boot is
// deliberately validation-resilient (a hand-edited config still
// starts the daemon so the operator can repair it via /config), so
// enforce again here: failing agent-memory construction is an
// operator-visible startup error and keeps background consolidation
// from ever running typed writes into a backend that would reject
// them deep inside spawned work.
if config.memory.types.enabled || config.memory.consolidation_extract_facts {
let flag = if config.memory.types.enabled {
"memory.types.enabled"
} else {
"memory.consolidation_extract_facts"
};
let global_kind = backend_kind_from_dotted(&config.memory.backend);
if global_kind != "sqlite" {
anyhow::bail!(
"{flag} = true requires memory.backend = \"sqlite\" (typed memory storage is SQLite-only), but memory.backend = {:?}",
config.memory.backend
);
}
if !matches!(backend_kind, ConfigBackend::Sqlite) {
anyhow::bail!(
"{flag} = true requires every agent on the sqlite memory backend (typed memory storage is SQLite-only), but agents.{agent_alias}.memory.backend = {backend_kind:?}"
);
}
}
// Markdown branch: the wrapper composes per-agent dirs, not a
// shared backend. Skip the inner-backend factory entirely, but still
// apply the install-wide policy decorator to own and peer Markdown
// stores before composition.
if matches!(backend_kind, ConfigBackend::Markdown) {
let own_workspace = config.agent_workspace_dir(agent_alias);
let own: Arc<dyn Memory> = Arc::new(ScannedMemory::new(View on GitHub (pinned to 88bb9c8533)
Solutions
- Set `memory.backend = "sqlite"` if typed memory is required.
- Disable the flagged features (`memory.types.enabled = false`, `memory.consolidation_extract_facts = false`) if the current backend must stay.
- Audit the merged config for which layer set the flag — the message names the specific flag.
Example fix
# before [memory] backend = "lucid" types.enabled = true # after [memory] backend = "sqlite" types.enabled = true
Defensive patterns
Strategy: validation
Validate before calling
// Mirror the factory's rule before calling create_memory_for_agent
// (TOML: memory.types.enabled / memory.consolidation_extract_facts)
let typed_enabled = config.memory.types_enabled || config.memory.consolidation_extract_facts;
if typed_enabled && backend_kind_from_dotted(&config.memory.backend) != "sqlite" {
anyhow::bail!(
"typed-memory flags require memory.backend = \"sqlite\"; current: {:?}",
config.memory.backend
);
} Prevention
- Validate typed-memory flags against the global backend in a config lint step at startup.
- Document next to each typed-memory flag that it is SQLite-only so operators do not combine it with lucid/qdrant.
- When merging config layers, re-run the lint on the merged result, not on individual layers.
When it happens
Trigger: Calling create_memory_for_agent with a typed flag enabled while memory.backend is "lucid", "qdrant", "markdown", or "none" (backend_kind_from_dotted of the global backend != "sqlite").
Common situations: Enabling fact extraction/consolidation on deployments that run lucid for vector recall; merging config layers where one layer sets typed flags and another sets the backend; copying a typed-memory example config onto an existing non-sqlite deployment.
Related errors
- {flag} = true requires every agent on the sqlite memory back
- matrix: `homeserver` is required
- Cannot persist empty Telegram identity
- transcription.max_audio_bytes must be greater than zero
- Edge TTS binary_path must be a bare command name without pat
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/595483b51ab4cebc.
Report an issue: GitHub.