apollo-client: Store error: the application attempted to write an object with no provided id but the store already contains an id of...
Hey, Today in one of my applications I found this issue. I’m not sure if this is a bug or desired behaviour because I couldn’t find any information about it in the documentation.
The fix is quite easy, just add id
to the query
without id.
So the question is: should every query has defined id
for a resource?
It seems to work without id
but when there will be the next query with defined id
, this error appears.
I’m asking because I have a few other cases where external API doesn’t have id
so this problem can appear again in the future.
Intended outcome: Error shouldn’t appear and application should render data.
Actual outcome: Error appears
Network error: Error writing result to store for query
query PokemonQuery($id: ID) {
Pokemon(id: $id) {
name
url
createdAt
}
}
Store error: the application attempted to write an object with no provided
id but the store already contains an id of Pokemon:ciwnmyvxn94uo0161477dicbm
for this object.
How to reproduce the issue: https://codesandbox.io/s/mom8ozyy9
Check checkbox
in provided demo.
Version
- apollo-client@<1.6.0>
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 77
- Comments: 62 (10 by maintainers)
Commits related to this issue
- add id to speaker to prevent Apollo store errors link to issue: https://github.com/apollographql/apollo-client/issues/2510 — committed to weijiangan/kljs-events by weijiangan 5 years ago
- Add id to LibraryQuery.items.$.user This fixes the apollo issue when updating cache: https://github.com/apollographql/apollo-client/issues/2510 — committed to vfonic/martian-library by vfonic 5 years ago
- Fix download button error The graphQL error has been fixed. Ref: https://github.com/apollographql/apollo-client/issues/2510 — committed to pharmaziegasse/charm-webapp by Aichnerc 5 years ago
- Add id to all queries to work around apollographql/apollo-client#2510 — committed to schneefux/project-cards by schneefux 5 years ago
Hey @hinok 👋
This error only should occur when you have made a query with an
id
field for a portion, then made another that returns what would be the same object, but is missing theid
field.We are planning on making this just a warning (instead of throwing) but it does help a lot to keep the
id
field included in queries that share fieldsYou may forgot to select
id
in your query.Are you guys planning on converting this to a
warning
rather than error as @jbaxleyiii mentioned. We’re getting this too - fine to bring backid
’s but a warning would be preferable.👍 this is a blocking error for me. Please fix
Should this issue be re-opened, and only closed after it’s made to be just a warning?
Currently, if you make a change to one query by adding an ID field, you could be breaking other parts of your app that you haven’t touched at all (because they use queries without ids and you used a query with an id)
This
id
issue caused some of our production pages failure too. I expect Apollo could do more than throw an error and break the whole page. An explicit configuration that indicates using a field likeid
as the key to share the resources would be good.It seems like missing __typename on any level along side id field will also trigger this error
For what it’s worth, I don’t mind the current behavior, as long as it can be caught compile-time using a tool like
apollo-codegen
. The real issue here is that the scenarios that induce this error can be complex and missed by unit tests and quick human checks, but exist in real world usage.+1
For all the people still experiencing this issue-I’ve finally found out what is causing this issue. What helped to shed some light on it was switching from
apollo-cache-inmemory
toapollo-cache-hermes
. I experimented with Hermes hoping to mitigate this ussue, but unfortunatelly it fails to update the cache the same asapollo-cache-inmemory
. What is curious though is that hermes shows a very nice user friendly message, unlikeapollo-cache-inmemory
. This lead me to a revelation that cache really hits this problem when it’s trying to store an object type that is already in the cache with and ID, but the new object type is lacking it. Soapollo-cache-inmemory
should work fine if you are meticolously consistent when querying your fields. If you omitid
field everywhere for a certain object type it will happily work. If you useid
field everywhere it will work correctly. Once you mix queries with and without id that’s when cache blows up with this horrible error message.This is not a bug-it’s working as intended, it’s just not documented anywhere-see this spec.
I’ve added a warning to the caching doc here: https://github.com/apollographql/apollo-client/pull/4895
+1 on updateManySomething
+1
+1
Have a same problem 😃 Would like to see some solution…
+1
I have the same problem here, no solution so far?
any update on this issue @jbaxleyiii ?
+1
+1
+1
PSA: This can also happen if you try to write an object without an ID, as happened to me when I created an unauthenticated user by mutating with
{accessToken}
instead of{accessToken, id, ...rest}
+1
This feels like a very important gotcha in using Apollo GQL that should be documented explicitly and obviously, and be added to standard Apollo linters. Can we add this to the docs?
I ran into this today, I added a new subquery somewhere and it broke my whole app because it’s a Next.js app which uses both SSR and CSR and depending on the cached data it would randomly crash.
For instance, refreshing a page with cmd+shift+r to erase cache would work fine (SSR) but then when navigating to another page (CSR) it would randomly crash THE WHOLE THING, depending on which page is loaded.
This definitely SHOULD NOT throw an exception, but rather a warning (as proposed in 2017). And it should be made obvious in the docs that all query must have an “id” field for Apollo to work properly.
Also, it’s very hard to debug. Especially because the error message isn’t always
Store error: the application attempted to write an object with no provided id but the store already contains an id of
but most of the time onlyNetwork error: Error writing result to store for query
with the whole query behind… Quite complicated to understand what’s the issue at hand with such cryptic error messages.I eventually added
id
everywhere, in all fragments and queries to avoid this, and it works fine now.@alacret what if I don’t have ID on some of my object types?
I am sorry to say this, because I totally respect the work apollo team has done on apollo-client, but this issue is a shitshow. Excuse the profanity, but it seems that apollo team doesn’t think this is an actual bug. yet even the most experienced people like https://twitter.com/thekitze/status/1113871705498370049 keep running into problems here. They should either acknowledge this as a bug or they should amend documentation with a big red warning that you absolutely need to include
id
or_id
field in all of the object types you query. The docs only mention regarding this topic I found is here: https://www.apollographql.com/docs/react/advanced/caching#normalization and there it is claimed that there is a fallback. From that I would expect that cache handles even such results correctly and without any issues whatsoever.For all the people like me who still get this error daily on production apps where they can’t magically add
id
field everywhere I’ve wrote this terrible hack that you can add to your apps that will at least keep your react app from breaking:+1
We can’t use it in our projects with having this error.
@cecchi thanks for that visitor/linter! I dropped it into a graphql-code-generator plugin: https://github.com/homebound-team/graphql-id-linter cc @capaj
This eventually became enough of a pain in the neck that we wrote a validation rule/linter to ensure the “id” field was present in every possible GraphQL selection set. This rule is intended to be used with the GraphQL validation APIs.
Our implementation is wrapped up in some other tooling but these are the relevant bits:
Usage is something like this:
Looks like this is addressed in Apollo Client 3, specifically this PR from Ben to remove that error https://github.com/apollographql/apollo-client/pull/5904
Here’s the repro using
"@apollo/client": "3.0.0-beta.44"
, no longer erroring https://codesandbox.io/s/github/cheapsteak/test-ac-cache-store-bug/tree/master/?file=/src/index.jsA plugin sounds like a good idea. We use
graphql-codegen
too, but we run them in series: validate followed by codegen. Sincegraphql-codegen
uses@graphql-toolkit
under the hood we’re able to load the schema and documents once for both steps, using graphql-codegen’s programmatic API.If there’s enough interest I can publish the validate fn as a standalone package.
The Stackoverflow answer pointed to in this issue is actually the sensible one and actually solves this issue, which is not a bug by the way. I think this needs to be documented somewhere. In a nutshell: make sure to add id to all subselections of your queries this makes sure the cache identifies queries and selections properly… notice this has nothing to do with following a certain pattern whether you put ids somewhere else or not, it’s just that simple; put ids for sub-selections and to add to that especially for ones that recurse!
@capaj @Abhijeetjaiswalit just put the ID in all the Types, and that will solve the issue
Yeah me too, not sure why these issues keep getting closed. BTW this is a bug. If you require
id
field to be present in the query and you cannot cache it if it’s not there then sensible thing to do would be to show a warning. Not an error.Find this stack overflow can resolve my problem.
will there be a warning published? it’s not practical for all objects to have an id attribute
@capaj That’s a super hack bro.
I think that just apollo-client is not so battle-tested as other libraries. I’m assuming that the decision was based on the fact that using
id
or_id
is pretty much a standard nowadays, and this was more relevant for the implementation of the cache than anything else.But it makes sense that by now this should be just a warning and not an error, or maybe allow to skip any caching check, or to allow setting a different field name as the key for the cache.
having this error
same problem
except it does update the cache, but the component does not receive the new props untill a different action takes place. say a mutation. I noticed this because i have an unrelated query that polls the server, when the query runs this component updates and shows the load more results.
I have also tried to refetch from the cache directly
Updated to
@apollo/client v3.4.5
, still had the issue. Would break my entire React component. Resolved it by making sure that nested data in the schema has the ID field (whatever the field is named) queried as well, e.g.Be careful include
__typename
or avoid it if you’re testing with MockProvider. But in some cases you have to include__typename
allowing it in the MockProviderI think the biggest that bothers me with this error is that it doesn’t seem to fire the
onError
error link when it occurs, unlike traditional GraphQL errors.@bennypowers shoot, I missed your comment, but I’d forgotten to make the `@homebound/graphql-id-linker~ npm module public; it should work now.
Looks like this wasn’t published yet?
@cecchi wow, this is amazing work! Someone should take that code and turn it into a code into a graphql-codegen plugin
I have a similar issue when an alias is used for the
ID
field:Example:
When I try to run the
MyProviderAccount
query afterGetService
I would get the error:I wasn’t expecting that when I use an alias for a field, I have to use the same alias everywhere so that cache would workEdit: It’s related to the
id
key not the alias. Using different aliases would still resolve data from cache if it’s available:Running the above queries in sequence - first A then B (or reverse) would not make a 2nd request, but resolve the 2nd query from cache
@wfsovereign , your answer enlighten a better picture, that is, just put id on every query or subquery that has an id field. Thanks 👍🏼
Is there a clear fix for this that (maybe) can simply show a warning if you try to run a graphl query without
id
defined? A bunch of people on my team have independently stumbled across this issue and it always takes about a day to figure out and resolve. If apollo-client could at least throw a warning when there is no id set on the query, at least we could create an automated ticket warning the developer that their query may (will) cause a bug. I/we would be very happy to support any efforts in this direction.This error is odd. It made one of our queries fail despite the fact that the query itself was just fine. There are valid cases for making similar nested queries where one has id and the other doesn’t. It’s good that we are warned that Apollo is unable to update the store but it shouldn’t break the app.