Repository navigation
Description
Summary
When a declarative Agent runs on the Go ADK runtime (runtime: go) with long-term memory enabled (OpenAI embedding provider), save_memory fails at embedding generation with HTTP 401 invalid_issuer. Nothing is persisted, so cross-session load_memory returns memories: null.
The exact same agent config on the Python runtime works — the embedding call to api.openai.com/v1/embeddings returns 200 and the memory is saved. Since the default declarative runtime is now go, memory-enabled agents silently stop persisting memory.
Environment
- kagent OSS
v0.10.0-beta1 - Go runtime image:
cr.kagent.dev/kagent-dev/kagent/golang-adk@sha256:0be1b7a0fe9560b097351cd97c2f71accf7f6f288fcdc0d5d6aae57e66d81b01 - Python runtime image:
cr.kagent.dev/kagent-dev/kagent/app@sha256:ed96ed74b55eaceb92aec97dd84a0f523645c7372e501db9a019b637c7f67ee5 - Embedding
ModelConfig:provider: OpenAI,model: text-embedding-3-small; key is a valid OpenAI service-account key (sk-svcacct-…)
Error (Go agent pod)
msg: Tool execution failed tool: save_memory caller: agent/agent.go:408
error: failed to generate embedding: API returned status 401: {
"error": {
"message": "Your authentication token is not from a valid issuer.",
"type": "invalid_request_error",
"code": "invalid_issuer",
"param": null
},
"status": 401
}
Root cause (narrowed)
The Go embedding path is go/adk/pkg/embedding/embedding.go → openAIProvider.generate(), which POSTs to <base_url | https://api.openai.com/v1>/embeddings with Authorization: Bearer os.Getenv("OPENAI_API_KEY") and dimensions: 768.
Everything that request depends on is valid — only the Go runtime fails:
| Test | Result |
|---|---|
Configured key + {"model":"text-embedding-3-small","dimensions":768} → OpenAI embeddings, from host |
200 |
| Same request from a pod in the agent's namespace (same egress) | 200 |
| Python runtime agent, identical config → embeddings | 200, memory saved (httpx log: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK") |
| Chat completions with the same key (Go agent) | works |
| Go runtime agent → embeddings | 401 invalid_issuer |
The Go and Python pods are identical for the embedding auth path — same config.json (model: openai/…, base_url ""; memory.embedding: {provider: openai, model: text-embedding-3-small}), same OPENAI_API_KEY sourced from the same secret, and no base_url/proxy/OBO env in either. The only difference is the runtime image.
The non-OpenAI error body shape ("status": 401 alongside the error object; code: invalid_issuer) suggests the Go runtime is sending a different Authorization token (or hitting a different endpoint) than the configured OpenAI key against api.openai.com, rather than the raw OPENAI_API_KEY that works everywhere else.
Reproduction
- Deploy a declarative
Agentwithruntime: goandmemoryenabled, using an OpenAI embeddingModelConfig(text-embedding-3-small). - Send a message that triggers
save_memory, e.g. "My favorite color is blue. Please remember that." - Pod log shows
save_memory … failed to generate embedding: API returned status 401 … invalid_issuer; thememorytable stays empty. - Switch the same
Agenttoruntime: pythonand repeat → the embedding call returns200and a row is persisted.
Expected
The Go ADK memory embedding path should use the same working OpenAI credential/endpoint as chat completions (and as the Python runtime), so save_memory persists memories.
Workaround
Pin memory-enabled agents to runtime: python.
🤖 Filed with Claude Code
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
fix(go-adk): openai embeddings generation (#2132)