zeroclaw-labs/zeroclaw · error

postgres backend requires storage config; call create_memory

Error message

postgres backend requires storage config; call create_memory_with_storage_and_routes instead of create_memory_with_builders

What it means

create_memory_with_builders constructs memory from a MemoryBackendKind plus builder closures, and that signature has no way to carry the PostgreSQL connection settings ([storage.postgres.<alias>]) the postgres backend requires. Rather than inventing connection defaults, the factory refuses the postgres kind on this entry point and points at the API that accepts full storage config. This is an API-shape mismatch, not an environment problem.

Source

Thrown at crates/zeroclaw-memory/src/lib.rs:173

) -> anyhow::Result<Box<dyn Memory>>
where
    F: FnMut() -> anyhow::Result<SqliteMemory>,
{
    match classify_memory_backend(backend_name) {
        MemoryBackendKind::Sqlite => {
            wrap_scanned_and_audit(sqlite_builder()?, policy, workspace_dir, audit_enabled)
        }
        MemoryBackendKind::Lucid => {
            let local = sqlite_builder()?;
            wrap_scanned_and_audit(
                LucidMemory::new("lucid", workspace_dir, local),
                policy,
                workspace_dir,
                audit_enabled,
            )
        }
        MemoryBackendKind::Postgres => {
            anyhow::bail!(
                "postgres backend requires storage config; \
                 call create_memory_with_storage_and_routes instead of create_memory_with_builders"
            )
        }
        MemoryBackendKind::Qdrant | MemoryBackendKind::Markdown => wrap_scanned_and_audit(
            MarkdownMemory::new("markdown", workspace_dir),
            policy,
            workspace_dir,
            audit_enabled,
        ),
        MemoryBackendKind::None => wrap_scanned_and_audit(
            NoneMemory::new("none"),
            policy,
            workspace_dir,
            audit_enabled,
        ),
        MemoryBackendKind::Unknown => {
            ::zeroclaw_log::record!(WARN, ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note).with_outcome(::zeroclaw_log::EventOutcome::Unknown).with_attrs(::serde_json::json!({"backend_name": backend_name, "unknown_context": unknown_context})), "Unknown memory backend '', falling back to markdown");

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Route postgres configs through create_memory_with_storage_and_routes (or create_memory_from_config), which resolves the [storage.postgres.<alias>] entry.
  2. If you must keep one call site, dispatch: builders API for sqlite/markdown-family backends, storage-aware factory for postgres.

Example fix

// before
let mem = create_memory_with_builders(
    &"postgres".to_string(), workspace_dir,
    || build_sqlite(...), "", &config.policy, config.audit_enabled,
)?;

// after
let mem = create_memory_from_config(&config, api_key)?;
Defensive patterns

Strategy: type-guard

Validate before calling

if matches!(classify_memory_backend(&backend_name), MemoryBackendKind::Postgres) {
    anyhow::bail!(
        "postgres backend requires storage config; use create_memory_with_storage_and_routes"
    );
}

Type guard

fn builders_api_supports(kind: MemoryBackendKind) -> bool {
    !matches!(kind, MemoryBackendKind::Postgres)
}

Prevention

When it happens

Trigger: Calling create_memory_with_builders with MemoryBackendKind::Postgres, or reaching it via create_memory_for_migration with a postgres backend. Typical trigger: a generic dispatch layer that maps backend strings to kinds and funnels every backend through the builders API.

Common situations: Code that treats all backends uniformly through the builders API; tests written against sqlite and later pointed at postgres; refactors that bypass the Config-based factories; copy-pasted factory calls from sqlite-only code paths.

Related errors


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