Skip to content

fix: page-by-URI over-resolution and homepage resolution in subdirectory installs#3965

Merged
jasonbahl merged 4 commits into
mainfrom
fix/3042-uri-over-resolution
Jun 24, 2026
Merged

fix: page-by-URI over-resolution and homepage resolution in subdirectory installs#3965
jasonbahl merged 4 commits into
mainfrom
fix/3042-uri-over-resolution

Conversation

@jasonbahl

Copy link
Copy Markdown
Collaborator

Fixes two related URI-resolution bugs in NodeResolver. They are shipped together because both live in resolve_uri() and the regression tests for each must not regress the other (the homepage-in-subdirectory case is on #3042's don't-regress list).

#3042 — typed idType: URI fields over-resolve partial/wrong-hierarchy URIs

Typed idType: URI fields (page, post, contentNode, and the per-post-type single fields) pre-seed the target post_type into the query vars before running WP_Query. When the requested path does not match a rewrite rule, parse_request() flags a 404, but the pre-seeded post_type turns the request into an unbounded query, so WP_Query returns an arbitrary post. nodeByUri, which passes no extra query vars, correctly returns null for the same path.

The 404 guard in resolve_uri() was gated on empty( $extra_query_vars ), so it only ran for nodeByUri and never for typed fields. The guard is refined to bail on a 404 unless the request is an explicit slug lookup (idType: SLUG), which passes a name and intentionally resolves by post_name without requiring the full path to match a rewrite rule.

Result: page(id: "/child/", idType: URI) now returns null for a partial or wrong-hierarchy path (matching nodeByUri), while the correct full path still resolves, including same-slug-different-parent pages.

#3775 — homepage returns null via its full URL in subdirectory installs

When WordPress is installed in a subdirectory, the full home URL (e.g. /blog/) resolved to null. Only a literal / was treated as the home page; for the full home URL, parse_request() strips the home path and leaves an empty request that resolve_uri() did not recognize as the home page.

The home page is now detected from the parsed request (an empty $wp->request with no node- or archive-identifying query var) in addition to the literal /, so the full home URL resolves regardless of the subdirectory name. The detection only applies when permalink parsing ran, so plain-permalink installs keep relying on the literal / check.

Tests

Both fixes were verified to leave the existing NodeByUriTest, PageByUriTest, and NodeBySlugTest suites green, and the don't-regress cases (#3582 percent-encoding, #2191 date archives) continue to pass. PHPCS and PHPStan (level 8) are clean.

Closes #3042
Closes #3775

…URIs

Typed `idType: URI` fields (page, post, contentNode, and other post type
single fields) pre-seed the target `post_type` into the query vars before
running WP_Query. When the requested path does not match a rewrite rule,
parse_request() flags a 404 but the pre-seeded `post_type` turns the
request into an unbounded query, so WP_Query returns an arbitrary post.
nodeByUri, which passes no extra query vars, correctly returns null for the
same path.

The 404 guard in resolve_uri() was gated on `empty( $extra_query_vars )`, so
it only ran for nodeByUri and never for typed fields. Refine the guard to
bail on a 404 unless the request is an explicit slug lookup (idType: SLUG),
which passes a `name` and intentionally resolves by post_name without
requiring the full path to match a rewrite rule.

Adds a regression test asserting typed idType:URI and nodeByUri resolve a
hierarchical page consistently: a partial/wrong-hierarchy URI returns null
for both, and a same-slug-different-parent URI resolves the correct node.

Closes #3042
When WordPress is installed in a subdirectory, the full home URL (e.g.
`/blog/`) resolved to null. Only a literal `/` was treated as the home
page; for the full home URL, parse_request() strips the home path and
leaves an empty request, which resolve_uri() did not recognize as home.

Detect the home page from the parsed request (an empty `$wp->request` with
no node- or archive-identifying query var) in addition to the literal `/`,
so the full home URL resolves regardless of the subdirectory name. The
detection only applies when permalink parsing ran, so plain-permalink
installs keep relying on the literal `/` check.

Adds a regression test that simulates several subdirectory names (including
a nested path) and asserts the full home URL resolves the front page while
a real page below the home still resolves normally.

Closes #3775
@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
wpgraphql-com Ready Ready Preview, Comment Jun 24, 2026 8:21pm

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.36842% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 83.6%. Comparing base (902d872) to head (9f407ed).

Files with missing lines Patch % Lines
plugins/wp-graphql/src/Data/NodeResolver.php 97.4% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##              main   #3965   +/-   ##
=======================================
  Coverage     83.6%   83.6%           
- Complexity    5330    5337    +7     
=======================================
  Files          286     286           
  Lines        22866   22901   +35     
=======================================
+ Hits         19111   19151   +40     
+ Misses        3755    3750    -5     
Flag Coverage Δ
wp-graphql-acf-wpunit-twentytwentyfive-single 77.5% <ø> (ø)
wp-graphql-wpunit-twentytwentyfive-single 84.7% <97.4%> (+0.1%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
plugins/wp-graphql/src/Data/NodeResolver.php 87.4% <97.4%> (+3.5%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jasonbahl jasonbahl merged commit c630f39 into main Jun 24, 2026
64 checks passed
@jasonbahl jasonbahl deleted the fix/3042-uri-over-resolution branch June 24, 2026 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant