# Deleting GraphQL node with xid (String @id) does not cleanup edges to that node

**URL:** <https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078>\
**Category:** GraphQL\
**Created:** [July 26, 2021, 1:45am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078 "2021-07-26T01:45:05Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [July 26, 2021, 1:45am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/1 "2021-07-26T01:45:05Z")

</div>

## Report a GraphQL Bug

### What edition and version of Dgraph are you using?

Dgraph Cloud

Edition:

- SlashGraphQL
- Dgraph (community edition/Dgraph Cloud)

If you are using the community edition or enterprise edition of Dgraph, please list the version:

> **Dgraph Version**
>
> ```auto
> $ dgraph version
>  
> PASTE YOUR RESULTS HERE
> 
> ```

### Have you tried reproducing the issue with the latest release?

N/A

### Steps to reproduce the issue (paste the query/schema if possible)

### Expected behaviour and actual result.

For this schema:

```auto
type Block {
  id: String! @id
  blocks: [Block!]!
}

```

And these mutations:

```auto
mutation {
  addBlock(input:{id:"test1", blocks:[{id:"test2", blocks:[]}]}) {
    block {
      id
      blocks {
        id
      }
    }
  }
}

```

```auto
mutation {
  deleteBlock(filter:{id:{eq:"test2"}}) {
    numUids
  }
}

```

This query will fail:

```auto
query {
  getBlock(id:"test1") {
    blocks {
      id
    }
}

```

With the error:

```auto
Non-nullable field 'id' (type String!) was not present in result from Dgraph. GraphQL error propagation triggered.

```

A DQL query shows that while the fields of the `test2` node have been deleted, the edge from `test1` to the dgraph uid of the node still exists.

---

<div class="post-metadata">

**Author:** ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)\
**Post date:** [July 26, 2021, 3:09am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/2 "2021-07-26T03:09:18Z")

</div>

Just curious, what happens if you also include the ID in the schema?

```auto
type Block {
  uid: ID!
  id: String! @id
  blocks: [Block!]!
}

```

Then you can query the results without requesting the `Block.id` that was deleted to see if the relationship still exists or not.

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [July 26, 2021, 3:13am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/3 "2021-07-26T03:13:45Z")

</div>

That works, but is more of a work around than a solution 🙂

---

<div class="post-metadata">

**Author:** ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)\
**Post date:** [July 26, 2021, 3:15am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/4 "2021-07-26T03:15:44Z")

</div>

Just trying to identify where the breakdown is. Is the relationship not being removed like it should, or is the problem with the query? I probably should run this to see it for myself instead of just keyboard warrior here trying to hash this out.

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [July 27, 2021, 11:51pm UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/5 "2021-07-27T23:51:01Z")

</div>

Any thoughts from team Dgraph? Seems to make external IDs somewhat unusable…

---

<div class="post-metadata">

**Author:** ![jdgamble555](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/jdgamble555/32/7503_2.png) [@jdgamble555](https://discuss.dgraph.io/u/jdgamble555)\
**Post date:** [July 28, 2021, 1:43am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/6 "2021-07-28T01:43:47Z")

</div>

Try it with @cascade:

> [@Querying entities with contained entities](http://discuss.hypermode.com/t/querying-entities-with-contained-entities/7081):
>
> I have a question which is probably a general GraphQL issue, not necessarily a dgraph issue, but thought maybe someone would be kind to lend a hand. Take this schema type Player { name: String! @id attributes: [PossessedAttribute] @hasInverse(field:player) } type Attribute { name: String! @id } type PossessedAttribute { id: ID! player: Player! attribute: Attribute! level: Int! } For argument’s sake, assume that the Attribute entity is indeed “entity-worthy”. In o…

J

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [July 28, 2021, 1:32pm UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/7 "2021-07-28T13:32:59Z")

</div>

Thank you for the suggestion. Not really looking for a work around, just raising a bug and wondering whether I should wait for a fix or work around in my codebase (which will mean removing the work around once it’s fixed 😅)

---

<div class="post-metadata">

**Author:** ![jdgamble555](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/jdgamble555/32/7503_2.png) [@jdgamble555](https://discuss.dgraph.io/u/jdgamble555)\
**Post date:** [July 28, 2021, 3:23pm UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/8 "2021-07-28T15:23:20Z")

</div>

I don’t know that that is a workaround, but possibly the fix. Let me know if it works.

J

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [July 28, 2021, 11:39pm UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/9 "2021-07-28T23:39:56Z")

</div>

It does work, but it’s surely a workaround 🙂 I asked Dgraph to delete that node, which should include removing all edges to that node as well – it shouldn’t be a huge change to the GraphQL query generator to filter out results with no dgraph.type (which is a good indication that they’ve been deleted)

---

<div class="post-metadata">

**Author:** ![jdgamble555](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/jdgamble555/32/7503_2.png) [@jdgamble555](https://discuss.dgraph.io/u/jdgamble555)\
**Post date:** [July 28, 2021, 11:57pm UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/10 "2021-07-28T23:57:39Z")

</div>

I think you’re talking about two different things. The @cascade is not a workaround, but does solve your query problem. What you actually want, is a _ **cascade on delete** _ that just removes the connection(s).

This is a feature request that I made a while back. Hopefully we will see this one day, as this is how SQL handles the situation:

> **[Feature Request: Cascade Delete & Deep Mutations By Reference Directive](https://discuss.dgraph.io/t/feature-request-cascade-delete-deep-mutations-by-reference-directive/14658)**
>
> Experience Report for Feature Request Update: 7/1/21 - to comply with Feature Request Template: What you wanted to do 1.) Update nested nodes from the parent Update Mutation. 2.) Delete nested nodes from the parent Delete Mutation 3.) Choose...

J

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [July 29, 2021, 2:01pm UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/11 "2021-07-29T14:01:10Z")

</div>

Basically what you are suggesting is that someone using the GraphQL endpoint should add @cascade to any edge query if the want to be able to delete nodes. Do I understand that correctly?

I totally understand the why of the issue, I’m just saying that any user that is not familiar with the way Dgraph (not just the GraphQL endpoint) works will think this is a bug.

Since these information-less edges serve no purpose to the GraphQL endpoint, I’m suggesting that they should be filtered out by the endpoint.

Since there are no Github issues for Dgraph any more all I can do is start a thread about it where we discuss workarounds 🙂

---

<div class="post-metadata">

**Author:** ![jdgamble555](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/jdgamble555/32/7503_2.png) [@jdgamble555](https://discuss.dgraph.io/u/jdgamble555)\
**Post date:** [July 30, 2021, 12:04am UTC](https://discuss.dgraph.io/t/deleting-graphql-node-with-xid-string-id-does-not-cleanup-edges-to-that-node/15078/12 "2021-07-30T00:04:39Z")

</div>

So @cascade is not the problem here, and is working as expected. Here is what [@cascade does from the docs](https://dgraph.io/docs/graphql/queries/cascade/):

> With the `@cascade` directive, nodes that don’t have all fields specified in the query are removed. This can be useful in cases where some filter was applied and some nodes might not have all the listed fields.

So this is correct. The real bug here is that the “informationless edges,” or “Non-nullable fields” are allowed to exist in the first place. There are only two possible fixes for this:

1. Don’t allow them to be deleted if one edge requires it to exist (Dgraph needs to return an error in this case)
2. Cascade delete both edges (if my @reference directive is added) - not to be confused with @cascade directive, completely different things…

The other option is what is currently happening: allowing a node with non-nullable fields to exist.

We hate this option, as it opens up a world of bad schema validation, potential query errors, etc.

@cascade is really just a filter. We don’t want unnecessary filters as our default way of querying.

J
