apollo-client: Getting Store Errors after upgrading to v1.0.0

Since upgrading from a previous release candidate (rc6), I am now getting errors when running ALL of my create/delete mutations, regardless of what data they mutate I always get the same error:

Allergen.jsx:38 Error: Error: Store error: the application attempted to write an object with no provided id but the store already contains an id of Site:developer for this object.
    at writeFieldToStore (http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:49816:23)
    at http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:49709:17
    at Array.forEach (native)
    at writeSelectionSetToStore (http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:49703:29)
    at writeResultToStore (http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:49688:12)
    at http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:51277:20
    at http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:50464:34
    at Array.forEach (native)
    at data (http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:50463:43)
    at apolloReducer (http://localhost:3000/packages/modules.js?hash=c1dea742144f5f0b244684fb3a95fddf714f326e:50675:23)
(anonymous) @ Allergen.jsx:38
(anonymous) @ meteor.js?hash=27829e9…:1105

In this particular instance I was attempting to delete an Allergen.

For reference here is the relevant client-side code:


const Allergen = ({ ..., removeAllergen }) => {
  const onDelete = () => {
    bootbox.confirm(`Are you sure that you wish to delete allergen '${allergen.name}'?`,
      (result) => {
        if (!result) return;
        removeAllergen({ id: allergen._id }).catch((methodError) => {
          toastr.error('An error occurred when attempting to delete the allergen');
          console.error('Error:', methodError);
        });
      },
    );
  };

  ...
};

const removeAllergen = gql`
  mutation removeAllergen($id: String!) {
    removeAllergen(id: $id)
  }
`;

const AllergenContainer = compose(
  graphql(removeAllergen, {
    props({ mutate }) {
      return {
        removeAllergen({ id }) {
          return mutate({
            variables: { id },
          });
        },
      };
    },
  }),
)(Allergen);

export default AllergenContainer;

and the server-side mutation:

export const schema = [`
  type Allergen {
    _id: String!
    createdAt: Date
    updatedAt: Date
    site: Site!
    siteId: String!
    name: String!
  }
`];

export const mutations = `
  # Deletes the specified allergen
  removeAllergen(id: String!): String
`;

export const mutationResolvers = {
  removeAllergen(root, { id }, context) {
    if (!context.user) throw new Meteor.Error('allergens.removeAllergen.login', 'Must be logged in.');

    const allergen = Allergens.findOne({ _id: id });
    if (!allergen) throw new Meteor.Error('allergens.removeAllergen.notFound', 'The specified allergen does not exist');
    userIsOwner(allergen, context.user);

    // Remove the allergen from the database and return the id of the removed document
    const docsRemoved = Allergens.remove({ _id: id });
    return docsRemoved === 1 ? id : null;
  },
};

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 18 (13 by maintainers)

Commits related to this issue

Most upvoted comments

I know this one is closed, but I am getting this error after updating from 0.10.1 to 1.3.0… Are you sure that it is fixed? I am not using meteor…

EDIT: Never mind. It turned out that I had an EventList query which cached events by their id and an Event query that didn’t include said id. Maybe this can help someone else 😃

Ok, after thinking for bit and looking at the code I’m fairly sure I know what’s going on. The issue is that reducer takes its query from observableQuery.options.query, which does not yet have the addTypename transform applied. The workaround is to add __typename to all selection sets in queries that have a reducer. I’m not sure if updateQueries has the same issue (it’s not trivial to check), but update doesn’t, because I recently fixed it (I think).

The quick solution would be to apply the addTypename transform every time the reducer runs (it’s pretty cheap). A slightly longer term solution might be to just apply addTypename as soon as the document enters ApolloClient through query or watchQuery, as we do for mutate. In the long term, we’d like to apply the transform only where it’s really necessary, and return only the selections that the user originally requested, not including __typename if it wasn’t asked for.

PS: It’s interesting that this only showed up after we created a default dataIdFromObject function. I would have assumed that such a problem would show up much sooner. It guess it shows that most people weren’t using dataIdFromObject.

I can confirm I’ve been running into pretty clear-cut issues with mutation updates. I’m not using meteor-integration btw.