headroomlabs-ai/headroom · error · ValueError
openai_api_key is required for OpenAI embedder
Error message
openai_api_key is required for OpenAI embedder
What it means
Choosing the OpenAI embedder requires an API key, and the factory validates this BEFORE consulting the process-wide embedder cache (the cache key is (backend, model) and omits the key, so a cached instance could otherwise mask a missing key for a later caller). ValueError is raised when config.embedder_backend is OPENAI and config.openai_api_key is falsy.
Source
Thrown at headroom/memory/factory.py:169
sentence-transformers / ONNX model-load cost more than once.
Args:
config: Memory system configuration.
Returns:
An Embedder implementation based on config.embedder_backend.
Raises:
ValueError: If the embedder backend is not supported.
"""
# Validate inputs ahead of the cache. The cache key is
# ``(backend, model)`` and intentionally does NOT include the API
# key — but that means a cached OpenAI embedder would shadow the
# config-validation step for a subsequent caller who forgot to pass
# ``openai_api_key``. Run the validation up front instead.
if config.embedder_backend == EmbedderBackend.OPENAI and not config.openai_api_key:
raise ValueError("openai_api_key is required for OpenAI embedder")
key = (
config.embedder_backend.value
if hasattr(config.embedder_backend, "value")
else str(config.embedder_backend),
config.embedder_model or "",
# The Ollama backend is built with ``base_url=config.ollama_base_url``,
# so two configs that share a backend and model but point at different
# Ollama servers must NOT share a cached embedder — otherwise the second
# caller silently gets an embedder bound to the first server. (The
# ``openai_api_key`` omission is handled by the up-front validation
# above; ``ollama_base_url`` has no such guard and would just resolve to
# the wrong host.)
config.ollama_base_url or "",
)
with _EMBEDDER_CACHE_LOCK:
cached = _EMBEDDER_CACHE.get(key)View on GitHub (pinned to 322425c43b)
Solutions
- Pass the key explicitly: MemoryConfig(embedder_backend=EmbedderBackend.OPENAI, embedder_model="text-embedding-3-small", openai_api_key=os.environ["OPENAI_API_KEY"])
- Confirm the env var is actually visible to the process (print(bool(os.environ.get('OPENAI_API_KEY')))) — it is not picked up implicitly
- If you intended local embeddings, use EmbedderBackend.SENTENCE_TRANSFORMERS or OLLAMA instead of OPENAI
Example fix
# before
config = MemoryConfig(embedder_backend=EmbedderBackend.OPENAI)
# after
import os
config = MemoryConfig(
embedder_backend=EmbedderBackend.OPENAI,
openai_api_key=os.environ["OPENAI_API_KEY"],
) Defensive patterns
Strategy: validation
Validate before calling
if config.embedder_backend == EmbedderBackend.OPENAI and not config.openai_api_key:
raise RuntimeError("OPENAI_API_KEY not set; cannot use OpenAI embedder")
system = await create_memory_system(config) Type guard
def openai_embedder_ready(cfg: MemoryConfig) -> bool:
return cfg.embedder_backend != EmbedderBackend.OPENAI or bool(cfg.openai_api_key) Try / catch
try:
system = await create_memory_system(config)
except ValueError as e:
if "openai_api_key is required" in str(e):
fail_startup("missing OpenAI key for embedder")
raise Prevention
- Centralize key resolution: pull os.environ['OPENAI_API_KEY'] in one config builder
- Add a startup preflight that checks each configured backend's required secrets
- Note the embedder cache is keyed by (backend, model) only — validation cannot be skipped for later callers either
When it happens
Trigger: MemoryConfig(embedder_backend=EmbedderBackend.OPENAI) with openai_api_key unset/None/empty, passed to create_memory_system; or the OPENAI_API_KEY env var was expected but never read (the config field does not auto-populate from env in this path).
Common situations: Dev machine has OPENAI_API_KEY exported but the config object was built without it; key set in a .env file that was never loaded; CI secret missing; key string accidentally whitespace-empty.
Related errors
- OpenAI API key required. Provide api_key parameter or set OP
- Unknown embedder backend: {config.embedder_backend}
- bedrock_eventstream_parse_failed
- bedrock_eventstream_crc_mismatch
- OpenAI API key required. Set OPENAI_API_KEY environment vari
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/fd4519db13537b33.
Report an issue: GitHub.