langfuse-python icon indicating copy to clipboard operation
langfuse-python copied to clipboard

fix: evict prompt cache on NotFound error

Open Betensis opened this issue 3 months ago • 2 comments

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 NotFoundError in _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 and PromptCache.invalidate(prompt_name) to drop all entries for a prompt.
  • Add test_evict_prompt_cache_entry_when_refresh_returns_not_found and update fixtures to initialise _resources with PromptCache.

Original issue: https://github.com/langfuse/langfuse/issues/10138


[!IMPORTANT] Fixes prompt cache eviction on NotFoundError by updating cache handling logic and adding tests for verification.

  • Behavior:
    • In client.py, catch NotFoundError in _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 and PromptCache.invalidate(prompt_name) to drop all entries for a prompt.
  • Tests:
    • Add test_evict_prompt_cache_entry_when_refresh_returns_not_found in test_prompt.py to verify cache eviction on NotFoundError.
    • Update fixtures in test_prompt.py to initialize _resources with PromptCache.

This description was created by Ellipsis 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 NotFoundError from 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"

Betensis avatar Nov 16 '25 20:11 Betensis

CLA assistant check
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.

CLAassistant avatar Nov 16 '25 20:11 CLAassistant

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

Betensis avatar Nov 23 '25 16:11 Betensis

Thanks a lot for your contribution! I'll push it over the line in https://github.com/langfuse/langfuse-python/pull/1456

hassiebp avatar Dec 01 '25 10:12 hassiebp