zeroclaw-labs/zeroclaw · error
memory backend {:?} references a storage alias; construct me
Error message
memory backend {:?} references a storage alias; construct memory from the full Config so the selected alias is applied What it means
create_memory receives only a MemoryConfig. When memory.backend contains a dot (e.g. "qdrant.prod", "postgres.main"), the suffix is a storage alias that must be looked up in the full Config's [storage.*] sections, which this function does not have. It fails fast instead of silently dropping the alias and connecting to an arbitrary or default storage.
Source
Thrown at crates/zeroclaw-memory/src/lib.rs:491
api_key: explicit_api_key.or(inherited_api_key),
};
};
ResolvedEmbeddingConfig {
model_provider: concrete_provider,
model,
dimensions,
api_key: explicit_api_key.or(provider_key).or(inherited_api_key),
}
}
pub fn create_memory(
config: &MemoryConfig,
workspace_dir: &Path,
api_key: Option<&str>,
) -> anyhow::Result<Box<dyn Memory>> {
if config.backend.trim().contains('.') {
anyhow::bail!(
"memory backend {:?} references a storage alias; construct memory from the full Config so the selected alias is applied",
config.backend
);
}
create_memory_with_storage_and_routes(
config,
&[],
ActiveStorage::None,
workspace_dir,
api_key,
None,
)
}
/// Construct memory from the canonical loaded configuration.
///
/// Config-aware production paths should use this entrypoint so the selectedView on GitHub (pinned to 88bb9c8533)
Solutions
- Call create_memory_from_config (or create_memory_with_storage_and_routes) with the full Config so the alias resolves against [storage.*].
- If you only have a MemoryConfig by design, strip the alias and use a plain backend name ("sqlite", "lucid", "markdown").
Example fix
// before — config.memory.backend == "qdrant.prod" let mem = create_memory(&config.memory, workspace_dir, api_key)?; // after let mem = create_memory_from_config(&config, api_key)?;
Defensive patterns
Strategy: type-guard
Validate before calling
if config.memory.backend.trim().contains('.') {
anyhow::bail!(
"backend {:?} uses a storage alias; construct from the full Config",
config.memory.backend
);
} Type guard
fn backend_needs_full_config(backend: &str) -> bool {
backend.trim().contains('.')
} Prevention
- Default to create_memory_from_config everywhere; reserve create_memory for code that controls the backend string and keeps it alias-free.
- Lint configs at load time: any memory.backend containing '.' must be paired with a matching [storage.<family>.<alias>] section.
When it happens
Trigger: Passing a MemoryConfig whose backend is in alias (dotted) form to create_memory — commonly after extracting config.memory out of the full Config, or after constructing a MemoryConfig inline from operator docs that show dotted backend examples.
Common situations: Callers holding only the memory section of the config; tests that build MemoryConfig by hand and paste a dotted backend string; refactors that split Config and lose the storage half.
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
- memory backend 'qdrant' requires a `[storage.qdrant.<alias>]
- memory backend 'postgres' requires a `[storage.postgres.<ali
- memory backend 'none' disables persistence; choose sqlite, l
- unsupported room visibility '{other}': expected private or p
- channel '{}' does not support forge API requests
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/e985ca8f882d35d0.
Report an issue: GitHub.