Skip to main content

CrewAI memory=True: "Please provide an OpenAI API key" when you're not using OpenAI (embedder fix)

Updated 6 min readMarkdown

Disclosure: I work on MemorySync (I'm Mohammed, the founder). I drafted this page with AI assistance and checked it against the source thread and the official docs listed under Sources on Oct 28, 2026. I read the issue, the CrewAI memory docs and the crewAI 1.15.32 source; I didn't run a crew for this page.

Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).

The question

In crewAI GitHub issue #2943 (Jun 3, 2025), a developer's crew worked with cache=True but failed as soon as they added memory=True:

pydantic_core._pydantic_core.ValidationError: 1 validation error for Crew
  Value error, Please provide an OpenAI API key. You can get one at https://platform.openai.com/account/api-keys [type=value_error, input_value={'agents': [Agent(role=Ho...': True, 'memory': True}, input_type=dict]

Their crew (crewAI 0.121.0, Python 3.10):

synergistic_crew = Crew(
    agents=[holiday_agent, macro_agent, news_summarizer_agent, analysis_forecast_agent, user_query_agent],
    tasks=[holiday_task, macro_task, news_summarizer_task, analysis_forecast_task, user_query_task],
    process=Process.sequential,
    verbose=True,
    cache=True,
    memory=True,
)

Status (checked Oct 28, 2026): closed as completed on Jun 4, 2025. The maintainer's answer: "memory use Embedding features that by default use OpenAI as provider", so either define OPENAI_API_KEY or "use another provider for embeddings".

Skip the memory plumbing around this fix. Once the fix below is in, the MemorySync CrewAI guide shows how to add per-user memory with MemorySync. MemorySync doesn't fix this error itself. When you're ready, see MemorySync. Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).

Why it happens

Your agents' LLM and crew memory's embedder are separate settings. Memory turns text into vectors for search, and the CrewAI memory docs say that "Without a custom embedder, memory uses OpenAI text-embedding-3-large embeddings." So a crew whose agents run on Gemini, Claude or a local model still asks for an OpenAI key the moment memory is on.

On crewAI 0.121 the check fired while the Crew was being validated, hence the pydantic ValidationError. In crewAI 1.x the default embedder is created lazily, so the error shows up when memory is first used, not when you build the crew. In the 1.15.32 source (unified_memory.py) the message starts with Memory requires an embedder for vector search but initialization failed and lists the fixes: set OPENAI_API_KEY, pass a different embedder, or pass a callable. The docs also note that memory saves run in a background thread, and save errors are emitted as MemorySaveFailedEvent instead of crashing the agent, so check your logs too.

Fix 1: set an embedder for your provider

If you want memory without OpenAI, give the crew an embedder. With memory=True, the docs say "the crew's embedder config is passed through". Here's a local embedder through Ollama (config from the docs' provider examples):

from crewai import Crew, Process

crew = Crew(
    agents=[...],
    tasks=[...],
    process=Process.sequential,
    memory=True,
    embedder={
        "provider": "ollama",
        "config": {
            "model_name": "mxbai-embed-large",
            "url": "http://localhost:11434/api/embeddings",
        },
    },
)

The docs' provider reference table lists the other keys, including google-generativeai (set GOOGLE_API_KEY), azure (needs deployment_id), cohere, voyageai, amazon-bedrock (uses boto3 credentials), huggingface, jina, watsonx, sentence-transformer and custom. The table marks Ollama and Sentence Transformer as needing no API key.

Fix 2: build Memory yourself and set its LLM too

Memory also uses an LLM to analyze what it saves and recalls (scope, categories, importance). In the 1.15.32 source (crew.py), memory=True reuses the crew's chat_llm or the first agent's llm for that. When you create Memory() yourself, nothing is reused: its llm defaults to an OpenAI model. So pass both. The docs show this for fully local operation:

from crewai import Crew, Memory

memory = Memory(
    llm="ollama/llama3.2",
    embedder={"provider": "ollama", "config": {"model_name": "mxbai-embed-large"}},
)

crew = Crew(agents=[...], tasks=[...], memory=memory)

If you're happy to use OpenAI for embeddings only, the simplest fix is the one the maintainer gave: set OPENAI_API_KEY and leave the defaults alone.

Checklist

  1. Decide which provider embeds memory. It doesn't have to match your agents' LLM.
  2. memory=True: set embedder= on the Crew. Your own Memory(...): set embedder= and llm= on it.
  3. Provide that provider's credentials, or use Ollama or Sentence Transformer, which need none.
  4. Changed embedders on an existing local store? The docs warn about dimension mismatches; for local testing run crewai reset-memories -m or delete the local memory directory.
  5. Watch the logs for MemorySaveFailedEvent errors, since background save failures don't crash the agent.

Common questions

My agents use Gemini. Why does CrewAI want an OpenAI key at all? Because the embedder defaults to OpenAI whatever your agents' llm is. Setting llm on the agents doesn't change the embedder.

Does cache=True need an embedder? No. In the issue, the crew ran with cache=True and only failed once memory=True was added. Tool caching and memory are separate features.

Where does crew memory get stored? By default in LanceDB under ./.crewai/memory (or $CREWAI_STORAGE_DIR/memory), per the docs' Storage Backend section. You can pass your own StorageBackend with Memory(storage=...).

Skip the plumbing with MemorySync

Changing where memory is stored doesn't remove the embedder requirement. The MemorySync CrewAI guide says CrewAI "embeds with its own embedder" before calling storage, so you still need Fix 1 or Fix 2 when you use Memory(storage=MemorySyncStorage(user_id=...)). What it adds is a managed StorageBackend, so records outlive the container and can be scoped per user_id. The guide's agent tools (create_memorysync_tools) work differently: they send text to MemorySync and don't call CrewAI's embedder (checked in the crewai-memorysync 1.1.0 source). Read the guide first. For an overview of MemorySync, see the MemorySync homepage.

From the guide:

pip install crewai-memorysync
from crewai import Agent, Crew, Task
from crewai.memory import Memory
from crewai_memorysync import MemorySyncStorage

crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task],
    memory=Memory(
        storage=MemorySyncStorage(user_id="support-crew"),
    ),
)

crew.kickoff()
# Every record the crew saved is now stored on MemorySync: it survives
# redeploys and is shared by every service using this user_id. The
# facts in those records show up in Memory Explorer and in recall.

Snippet adapted from the MemorySync CrewAI guide; I haven't run it for this page.

Starter template: memorysyncio/memorysync-first-memory.

Sources

  • github.com/crewAIInc/crewAI/issues/2943 (closed as completed Jun 4, 2025, 2 comments; read 2026-10-28)
  • docs.crewai.com/en/concepts/memory (default embedder, crew embedder pass-through, provider reference, LLM configuration, storage backend, troubleshooting; read 2026-10-28)
  • crewAI 1.15.32 source: lib/crewai/src/crewai/crew.py (create_crew_memory, _memory_llm) and lib/crewai/src/crewai/memory/unified_memory.py (lazy embedder and LLM errors; read 2026-10-28)
  • MemorySync docs: docs.memorysync.io/guides/crewai; crewai-memorysync 1.1.0 (PyPI)

Next step: read the MemorySync CrewAI guide, then see MemorySync. Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).

About the author

  • Building MemorySync (memorysync.io) — persistent memory infrastructure for AI agents, Cursor, and Claude Code.

No comments yet. Be the first to comment.