[Bug] threads.search() returns threads deleted by TTL sweeper (eventual consistency issue) #1119

Open
opened 2026-02-20 17:43:09 -05:00 by yindo · 1 comment
Owner

Originally created by @jettxlove on GitHub (Jan 14, 2026).

Description

threads.search() returns threads that have been deleted by the checkpointer TTL sweeper. When a user tries to load one of these stale threads, they get a 404 HTTP error.

Expected Behavior

threads.search() should not return threads that have been deleted by the TTL sweeper, or the documentation should clearly describe this eventual consistency gap and recommended handling patterns.

Actual Behavior

  1. Thread data expires and is deleted by the TTL sweeper (configured via checkpointer.ttl in langgraph.json)
  2. The thread metadata still appears in threads.search() results
  3. When user tries to fetch the thread (e.g., load history), they get a 404 error

Configuration

"checkpointer": {
  "ttl": {
    "strategy": "delete",
    "sweep_interval_minutes": 60,
    "default_ttl": 43200
  }
}

Steps to Reproduce

  1. Create threads with the above TTL configuration
  2. Wait for threads to expire and be deleted by TTL sweeper
  3. Call threads.search() - stale threads may still appear
  4. Try to fetch thread history for a stale thread - 404 error

Workaround

We implemented a frontend workaround that catches the 404 error and removes the stale thread from the local UI state, preventing users from clicking on it again.

Environment

  • LangGraph Cloud
  • Using @langchain/langgraph-sdk JavaScript client
  • langgraph-server base image: langchain/langgraph-server:0.4.39

Questions

  1. Is this expected behavior (eventual consistency)?
  2. If so, what is the recommended pattern for handling this?
  3. Is there a timeline for improving index consistency with the TTL sweeper?

cc @jettlove

Originally created by @jettxlove on GitHub (Jan 14, 2026). ## Description `threads.search()` returns threads that have been deleted by the checkpointer TTL sweeper. When a user tries to load one of these stale threads, they get a 404 HTTP error. ## Expected Behavior `threads.search()` should not return threads that have been deleted by the TTL sweeper, or the documentation should clearly describe this eventual consistency gap and recommended handling patterns. ## Actual Behavior 1. Thread data expires and is deleted by the TTL sweeper (configured via `checkpointer.ttl` in `langgraph.json`) 2. The thread metadata still appears in `threads.search()` results 3. When user tries to fetch the thread (e.g., load history), they get a 404 error ## Configuration ```json "checkpointer": { "ttl": { "strategy": "delete", "sweep_interval_minutes": 60, "default_ttl": 43200 } } ``` ## Steps to Reproduce 1. Create threads with the above TTL configuration 2. Wait for threads to expire and be deleted by TTL sweeper 3. Call `threads.search()` - stale threads may still appear 4. Try to fetch thread history for a stale thread - 404 error ## Workaround We implemented a frontend workaround that catches the 404 error and removes the stale thread from the local UI state, preventing users from clicking on it again. ## Environment - LangGraph Cloud - Using `@langchain/langgraph-sdk` JavaScript client - `langgraph-server` base image: `langchain/langgraph-server:0.4.39` ## Questions 1. Is this expected behavior (eventual consistency)? 2. If so, what is the recommended pattern for handling this? 3. Is there a timeline for improving index consistency with the TTL sweeper? cc @jettlove
Author
Owner

@hinthornw commented on GitHub (Feb 5, 2026):

Hm 0.4.39 was EOL a while back. Do you see this in more recent versions?

This is not reproducible right now but also not expected.

@hinthornw commented on GitHub (Feb 5, 2026): Hm `0.4.39` was EOL a while back. Do you see this in more recent versions? This is not reproducible right now but also not expected.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#1119