zeroclaw-labs/zeroclaw · error · anyhow::Error

memory backend '{}' does not support StoreOptions kind/pinne

Error message

memory backend '{}' does not support StoreOptions kind/pinned/tenant_id; use a backend that overrides store_with_options

What it means

install_global_subscriber is the single logging entry point for daemon binaries: it stacks LogCaptureLayer under an alias-prefixed stderr formatter and calls tracing::subscriber::set_global_default. tracing allows exactly one global default per process; set_global_default returns Err when one is already installed, and this expect converts that into a panic. The crate already ships non-panicking siblings — try_install_capture_subscriber and try_install_line_sink_for_tests — which ignore the same error.

Source

Thrown at crates/zeroclaw-api/src/memory_traits.rs:561

        self.store(key, content, category, session_id).await
    }

    /// Store a memory entry with the full additive metadata surface.
    ///
    /// Default delegates through the existing metadata method for namespace and
    /// importance only. Backends that do not override this must fail explicitly
    /// when callers pass typed/full metadata, rather than silently discarding
    /// data needed by later typed-memory readers.
    async fn store_with_options(
        &self,
        key: &str,
        content: &str,
        category: MemoryCategory,
        session_id: Option<&str>,
        options: StoreOptions,
    ) -> anyhow::Result<()> {
        if options.requires_full_options_storage() {
            anyhow::bail!(
                "memory backend '{}' does not support StoreOptions kind/pinned/tenant_id; use a backend that overrides store_with_options",
                self.name()
            );
        }
        self.store_with_metadata(
            key,
            content,
            category,
            session_id,
            options.namespace.as_deref(),
            options.importance,
        )
        .await
    }

    /// Store a memory entry with full metadata and an explicit agent UUID.
    ///
    /// The compatibility default preserves agent attribution through the

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Install exactly once at process start; guard the call with std::sync::Once or check tracing::dispatcher::has_been_set() first.
  2. For secondary or embedded contexts use zeroclaw_log::try_install_capture_subscriber(), which ignores an already-set default.
  3. In tests, prefer per-test scoped subscribers (tracing::subscriber::with_default) or the crate's try_install_line_sink_for_tests().
  4. Grep the dependency graph for set_global_default, fmt::init, or env_logger init to find the competing installer.

Example fix

// before
zeroclaw_log::install_global_subscriber(None, "info", false);
zeroclaw_log::install_global_subscriber(None, "info", true); // second call panics

// after
static LOG_INIT: std::sync::Once = std::sync::Once::new();
LOG_INIT.call_once(|| zeroclaw_log::install_global_subscriber(None, "info", false));
Defensive patterns

Strategy: validation

Validate before calling

// Before installing:
if !tracing::dispatcher::has_been_set() {
    zeroclaw_log::install_global_subscriber(None, "info", false);
} else {
    zeroclaw_log::try_install_capture_subscriber(); // non-panicking fallback
}

Try / catch

// If third-party code may race you to the global default:
let r = std::panic::catch_unwind(|| {
    zeroclaw_log::install_global_subscriber(None, "info", false);
});
if r.is_err() {
    // another subscriber won the race; keep it and continue with its output
}

Prevention

When it happens

Trigger: Calling install_global_subscriber a second time, or calling it after anything else installed a global subscriber: tracing_subscriber::fmt::init() in another crate or test harness, env_logger's tracing bridge, or an embedding application that sets its own default.

Common situations: Integration test suites where an earlier test initialized logging; a dependency that calls init() itself; embedding zeroclaw in a host app that already configures tracing; a refactor that moves the install call onto a path executed more than once (e.g. per-agent instead of per-process).

Related errors


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