fix(resources): fetch federated resource live when cached content is NULL - #6504
Open
Ewertonslv wants to merge 1 commit into
Open
fix(resources): fetch federated resource live when cached content is NULL#6504Ewertonslv wants to merge 1 commit into
Ewertonslv wants to merge 1 commit into
Conversation
…NULL
In cache gateway mode, read_resource reads `content = resource_db.content`
for a federated resource. When both text_content and binary_content are NULL
(e.g. resources created via the migration / re-discovery path), the
Resource.content property raises ValueError("Resource has no content") before
the RESOLVE CONTENT block. The transport layer catches it and returns empty
content, so the client silently receives an empty read instead of the
upstream's real content.
Catch that ValueError in the cache-mode branch and, when the resource is
federated (has a gateway), build a metadata-only ResourceContent so the
existing RESOLVE CONTENT block fetches it live from the gateway -- the same
path already used for resources whose cached content is an empty string.
Non-federated resources have nothing to fetch, so the original error is
preserved.
Adds regression tests for the NULL-content federated read (fetches live) and
the non-federated case (error preserved, no live fetch attempted).
Refs IBM#5450
Signed-off-by: Ewerton Silva <ewertoncom297@gmail.com>
Ewertonslv
requested review from
Lang-Akshay,
brian-hussey,
crivetimihai,
ja8zyjits and
msureshkumar88
as code owners
August 31, 2026 17:33
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Related Issue
Refs #5450 (scoped to the NULL-content case — see Scope below; not an auto-close).
📝 Summary
In
cachegateway mode,ResourceService.read_resourcereadscontent = resource_db.contentfor a federated resource. When bothtext_contentandbinary_contentareNULL(e.g. resources created via themigration / re-discovery path,
createdVia: rediscovery), theResource.contentproperty raises
ValueError("Resource has no content")before the RESOLVECONTENT block. The transport layer catches the exception and returns empty
content, so the client silently receives an empty read instead of the upstream's
real content.
Fix
Catch that
ValueErrorin the cache-mode branch and, when the resource isfederated (has a gateway), build a metadata-only
ResourceContentso theexisting RESOLVE CONTENT block fetches it live from the gateway — the same
path already used for resources whose cached content is an empty string. A
non-federated resource has nothing to fetch, so the original error is preserved
(re-raised).
Tests (before → after)
..._null_content_federated_fetches_live: NULL content + gateway → without thefix,
ValueErrorpropagates and the read is empty; with the fix, the content isfetched live via
invoke_resource...._null_content_no_gateway_preserved: NULL content + no gateway → the"no content" error is preserved and no live fetch is attempted.
🔄 Rebase notes (2026-08-31)
Rebased onto current
main(ffcc0822) — clean rebase, no conflicts. Re-verifiedagainst today's
main:content = resource_db.content,so a federated row with NULL cached content still raises
ValueError: Resource has no contentinstead of proxying upstream.main,..._null_content_federated_fetches_livefails with thatValueError; with thehunk applied, both new tests pass.
pytest tests/unit/mcpgateway/services/test_resource_service.py— 309 passed.ruff check,ruff format --checkandblack --checkclean on both touched files.Coordination note (unchanged): this and the direct_proxy fix for #5451 both touch
read_resourceinresource_service.py, but they fix different bugs on differentcode paths and their hunks do not overlap, so they merge cleanly in either order and
neither depends on the other. Kept separate deliberately, per the one-concern rule.
Also: #5450 is no longer labeled
triage(it isbug/COULDnow), which was theconcern I flagged in my comment on the original PR.
🔎 Scope / follow-up (binary resources)
The issue also notes that binary federated resources read empty for a
separate reason:
invoke_resource's SSE/StreamableHTTP helpers extract the livepayload with
getattr(contents[0], "text")unconditionally, so aBlobResourceContents(e.g.image/png) yieldsNone. Fixing that cleanlyrequires
invoke_resourceto signal which field (text vs blob) the upstreamreturned — both are strings, so they can't be disambiguated after the fact — i.e.
a small change to its return contract, plus routing in the RESOLVE block. That is
a deliberate design decision I left out of this PR to keep it focused and
low-risk. Happy to follow up with that in a separate PR if you'd like — just let
me know your preference on the
invoke_resourcereturn shape.📏 Reviewability
triage🏷️ Type of Change