-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Summary
The /thoughts/{brainId}/{thoughtId}/graph endpoint returns stale link metadata — specifically, the name field on links may be null or show outdated values for hours or days after a successful PATCH /links/{brainId}/{linkId} update. The children array in the same response is always accurate.
This appears to be caused by aggressive response caching in the Azure App Service layer fronting api.bra.in.
Reproduction Steps
- Create a child thought under a parent
- PATCH the child link to set
name = "hasMember":→ Returns HTTP 200PATCH /links/{brainId}/{linkId} Content-Type: application/json-patch+json [{"op": "replace", "path": "/name", "value": "hasMember"}] - Immediately GET the graph:
GET /thoughts/{brainId}/{parentId}/graph - Inspect
links[]in the response — the link'snamefield is oftennulldespite the successful PATCH
Observed Behavior
- PATCH returns 200 — the write succeeds
- Individual link GET (
GET /links/{brainId}/{linkId}) sometimes returns the updated name, depending on which Azure instance serves the request - Graph endpoint (
GET /thoughts/{brainId}/{thoughtId}/graph) consistently returnsname: nullfor the same links, for hours after the update - Children array in the graph response is always correct (names, IDs are fresh)
modificationDateTimeon the stale graph response shows an old timestamp (e.g., 2 days prior), confirming the response is cached
Debugging Details
We tested extensively from multiple HTTP clients:
| Client | Same Request | name field |
modificationDateTime |
|---|---|---|---|
Long-lived httpx.AsyncClient (connection pooling) |
GET /thoughts/.../graph |
null |
2026-02-19 (stale) |
Fresh httpx.AsyncClient per request |
Same URL | "hasMember" |
2026-02-21 (fresh) |
Fresh client with Connection: close |
Same URL | Mixed results | Mixed |
Fresh client with Arr-Disable-Session-Affinity: True |
Same URL | Still stale on some requests | Stale |
The inconsistency across clients hitting the same endpoint with the same credentials strongly suggests Azure ARRAffinity session-pinning combined with per-instance response caching that doesn't invalidate when link metadata is updated via PATCH.
What We Tried (Workarounds)
Connection: closeheader — forces new TCP connections, partially helps locally but not from Azure-hosted callers (e.g., FastMCP Cloud → api.bra.in)Arr-Disable-Session-Affinity: Trueheader — did not resolve the issue; multiple Azure instances appear to have independently stale caches- Individual link GET (
GET /links/{brainId}/{linkId}) — more reliable than the graph endpoint but still inconsistent across instances
Impact
Any application that writes link metadata (names, labels, colors) and then reads it back via the graph endpoint will get stale data. This makes link metadata effectively unreliable for programmatic use cases like:
- Using labeled links for categorization or filtering
- Building indices based on link names
- Any workflow that writes then reads link properties
Our Workaround
We stopped relying on link metadata entirely. Our vault member discovery now enumerates the children array from the graph endpoint (which is always reliable) instead of filtering by link names.
Suggested Fix
The graph endpoint's response cache should be invalidated (or at least marked stale) when any link in the graph is updated via PATCH. Alternatively, add a Cache-Control: no-cache or ?_t=timestamp cache-busting option for callers that need fresh data.
Environment
- API endpoint:
https://api.bra.in - Client: Python
httpx0.27+ - Auth: Bearer token (valid API key)
- Date observed: 2026-02-21
- Tested from: macOS (local) and FastMCP Cloud (Azure-hosted)