fix: evict prompt cache on NotFound error
Problem
When a prompt label is removed in the Langfuse UI and the cached entry expires, get_prompt kept returning the stale prompt. The refresh worker logged a 404 NotFoundError but left the cache entry intact, so the SDK never fell back to another label or the unlabeled version. This bug is described in the issue linked below.
Technical details
- Catch
NotFoundErrorin_fetch_prompt_and_update_cache, log a warning and delete the cache entry before re‑raising the error. - Add
PromptCache.delete(key)to remove a single cached entry andPromptCache.invalidate(prompt_name)to drop all entries for a prompt. - Add
test_evict_prompt_cache_entry_when_refresh_returns_not_foundand update fixtures to initialise_resourceswithPromptCache.
Original issue: https://github.com/langfuse/langfuse/issues/10138
[!IMPORTANT] Fixes prompt cache eviction on
NotFoundErrorby updating cache handling logic and adding tests for verification.
- Behavior:
- In
client.py, catchNotFoundErrorin_fetch_prompt_and_update_cache, log a warning, and delete the cache entry before re-raising the error.- Add
PromptCache.delete(key)to remove a single cached entry andPromptCache.invalidate(prompt_name)to drop all entries for a prompt.- Tests:
- Add
test_evict_prompt_cache_entry_when_refresh_returns_not_foundintest_prompt.pyto verify cache eviction onNotFoundError.- Update fixtures in
test_prompt.pyto initialize_resourceswithPromptCache.This description was created by
for 3c32bb0ee185c654c5bd32ab5c885e6281138d2d. You can customize this summary. It will automatically update as commits are pushed.
Disclaimer: Experimental PR review
Greptile Summary
- Fixes stale prompt cache bug by evicting cache entries when background refresh receives 404
NotFoundErrorfrom API - Adds
PromptCache.delete()method to remove single cache entries when prompts are deleted in Langfuse UI
Confidence Score: 5/5
- This PR is safe to merge with minimal risk
- The fix is well-targeted with proper exception handling, safe cache deletion logic using
dict.pop(key, None), and comprehensive test coverage verifying the cache eviction flow - No files require special attention
Important Files Changed
| Filename | Overview |
|---|---|
| langfuse/_client/client.py | Added NotFoundError exception handling to evict cache entries when prompts are deleted from Langfuse UI |
| tests/test_prompt.py | Added comprehensive test for cache eviction on NotFoundError and updated fixture with _resources initialization |
Sequence Diagram
sequenceDiagram
participant User
participant Langfuse as "Langfuse.get_prompt()"
participant Cache as "PromptCache"
participant Worker as "Background Worker"
participant API as "Langfuse API"
User->>Langfuse: "get_prompt(name)"
Langfuse->>Cache: "get(cache_key)"
Cache-->>Langfuse: "cached_prompt (expired)"
Langfuse->>Cache: "add_refresh_prompt_task()"
Langfuse-->>User: "return stale prompt"
Cache->>Worker: "schedule refresh task"
Worker->>Langfuse: "call _fetch_prompt_and_update_cache()"
Langfuse->>API: "prompts.get(name, label)"
API-->>Langfuse: "NotFoundError (404)"
Langfuse->>Cache: "delete(cache_key)"
User->>Langfuse: "get_prompt(name, fallback)"
Langfuse->>Cache: "get(cache_key)"
Cache-->>Langfuse: "None"
Langfuse->>API: "prompts.get(name, label)"
API-->>Langfuse: "NotFoundError (404)"
Langfuse-->>User: "return fallback prompt"
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.
:white_check_mark: hassiebp
:x: Betensis
You have signed the CLA already but the status is still pending? Let us recheck it.
Hi @hassiebp, thanks for taking a look
Do you need anything else from my side to move this PR forward? I noticed that the CI tests failed, but the failures don’t seem related to the changes I introduced. Since the failures appear unrelated, I'm not sure whether I should address them or if they're tracked separately
Please let me know how to proceed
Thanks a lot for your contribution! I'll push it over the line in https://github.com/langfuse/langfuse-python/pull/1456