Skip to content

fix: apply query variable defaults when undefined is passed explicitly - #13364

Merged
jerelmiller merged 4 commits into
apollographql:mainfrom
atharv-sys32:fix/undefined-variable-defaults
Jul 29, 2026
Merged

fix: apply query variable defaults when undefined is passed explicitly#13364
jerelmiller merged 4 commits into
apollographql:mainfrom
atharv-sys32:fix/undefined-variable-defaults

Conversation

@atharv-sys32

@atharv-sys32 atharv-sys32 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #13345

Summary by CodeRabbit

  • Bug Fixes
    • Corrected GraphQL variable handling when variables are explicitly set to undefined.
    • Query-defined default values are now applied correctly, ensuring conditional fields such as those controlled by @include return the expected results.

When query variables like { show: undefined } are passed, the cache's
diffQueryAgainstStore would overwrite GraphQL-specified default values
with undefined by spreading the user-provided variables directly.
This caused @include/@Skip directives to fail with 'Invalid variable
referenced' errors.

Filter out undefined values before merging with defaults, matching the
behavior already implemented in QueryManager.getVariables.

Fixes apollographql#13345
@changeset-bot

changeset-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ecd2e19

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@apollo/client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@apollo-librarian

apollo-librarian Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

✅ AI Style Review — No Changes Detected

No MDX files were changed in this pull request.

Review Log: View detailed log

This review is AI-generated. Please use common sense when accepting these suggestions, as they may not always be accurate or appropriate for your specific context.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 57b38b6e-2e42-401f-bd18-6dbf54e92066

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The cache reader now removes explicitly undefined variables before merging query defaults. A test verifies that an undefined variable uses its default value when evaluating an @include directive.

Changes

Undefined variable default handling

Layer / File(s) Summary
Cache reader variable normalization and validation
src/cache/inmemory/readFromStore.ts, src/cache/inmemory/__tests__/readFromStore.ts
diffQueryAgainstStore filters undefined variables before applying query defaults, and a test confirms the conditional field is omitted when the default is false.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: benjamn

Poem

I’m a bunny with variables, undefined in my paw,
The cache finds the default and follows its law.
The hidden field stays tucked away,
While id hops out to play.
Clean defaults bring a bright new day!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main fix: ignoring explicit undefined variables so query defaults apply.
Linked Issues check ✅ Passed The code and test directly address issue #13345 by filtering undefined variables and letting the query default value apply.
Out of Scope Changes check ✅ Passed The change set stays focused on variable default handling and the supporting regression test, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jerelmiller jerelmiller left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the submission! I had a couple small points of feedback. Before we merge, can you also make sure this PR has a changeset? Otherwise this won't end up in the changelog. Thanks!

Comment thread src/cache/inmemory/readFromStore.ts Outdated
Comment on lines 207 to 213
const rawVariables = variables ?? {};
variables = {
...getDefaultValues(getQueryDefinition(query)),
...variables!,
...Object.fromEntries(
Object.entries(rawVariables).filter(([, v]) => v !== undefined)
),
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than spreading variables, then spreading it again (with a filter applied), lets instead use the compact utility which merges objects except undefined values.

Suggested change
const rawVariables = variables ?? {};
variables = {
...getDefaultValues(getQueryDefinition(query)),
...variables!,
...Object.fromEntries(
Object.entries(rawVariables).filter(([, v]) => v !== undefined)
),
};
variables = compact(
getDefaultValues(getQueryDefinition(query)),
variables
);

});
});

it("applies defaults when variable is explicitly undefined", () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great test! Can we also verify it correctly uses defaults if show is omitted altogether as well? I don't think we have any other test in this suite that verifies that. That just makes sure we don't add any regressions there as well 🙂

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test doesn't work at all since the field has no value in the store. So even if show: true was used (or defaulted), the query would return only { id: "abcd" } as the result?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ab-pm the readQueryFromStore helper that this test uses sets returnPartialData: false by default so if @include really weren't evaluated, the result would be null instead of { id: "abcd" } due to the result being a partial result. I think its ok 🙂

@atharv-sys32

Copy link
Copy Markdown
Contributor Author

Hey @jerelmiller , I've addressed all your feedback:

  • Replaced the manual spread/filter with the compact() utility
  • Added a test for entirely omitted variables as a regression guard
  • Added a changeset for the changelog

Would appreciate if you could take another look when you get a chance. Thanks!

@atharv-sys32
atharv-sys32 requested a review from jerelmiller July 29, 2026 04:48
Comment thread .changeset/pink-shoes-cheer.md Outdated

@jerelmiller jerelmiller left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for the contribution! I'll get this out in the next patch.

@jerelmiller
jerelmiller enabled auto-merge (squash) July 29, 2026 23:22
@pkg-pr-new

pkg-pr-new Bot commented Jul 29, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/@apollo/client@13364

commit: ecd2e19

@jerelmiller
jerelmiller merged commit 2f383e7 into apollographql:main Jul 29, 2026
48 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 29, 2026
@atharv-sys32

Copy link
Copy Markdown
Contributor Author

Hey @jerelmiller, thanks for the quick merge on this one! Really appreciate it.

If you have a moment, could you also take a look at #13365? It's the docs-only unique-names anchor fix - small change and already reviewed. Thanks!

jerelmiller pushed a commit that referenced this pull request Jul 30, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @apollo/client@4.2.9

### Patch Changes

- [#13364](#13364)
[`2f383e7`](2f383e7)
Thanks [@atharv-sys32](https://github.com/atharv-sys32)! - Fix a bug
where GraphQL variable default values were not applied during cache
reads when variables with defaults were explicitly set to `undefined`.
This caused `@include`/`@skip` directives to throw "Invalid variable
referenced" errors when the variable was passed as `undefined` instead
of being omitted entirely.

- [#13367](#13367)
[`2b39cc8`](2b39cc8)
Thanks [@jerelmiller](https://github.com/jerelmiller)! - Fix an issue
where some `@export` queries would not react to cache updates when the
fields keyed by exported variables were updated.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Default value does not apply to variable passed as undefined

3 participants