{"record":{"id":"b3a6b003bda0ce48","repo":"dgraph-io/dgraph","slug":"could-not-insert-duplicate-value-v-for-predicat","errorCode":null,"errorMessage":"could not insert duplicate value [%v] for predicate [%v]","messagePattern":"could not insert duplicate value \\[(.+?)\\] for predicate \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgraph/server.go","lineNumber":1824,"sourceCode":"\t\t\t\treturn errors.Wrapf(err, \"error while parsing [%v]\", pred.Subject)\n\t\t\t}\n\t\t}\n\n\t\tvar predValue interface{}\n\t\tif strings.HasPrefix(pred.ObjectId, \"val(\") {\n\t\t\tvarName := qr.Vars[pred.ObjectId[4:len(pred.ObjectId)-1]]\n\t\t\tval, ok := varName.Vals.Get(0)\n\t\t\tif !ok {\n\t\t\t\t_, isValueGoingtoSet := varName.Vals.Get(subjectUid)\n\t\t\t\tif !isValueGoingtoSet {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tresults := qr.Vars[queryVar.valVar]\n\t\t\t\terr := results.Vals.Iterate(func(uidOfv uint64, v types.Val) error {\n\t\t\t\t\tvarNameVal, _ := varName.Vals.Get(subjectUid)\n\t\t\t\t\tif v.Value == varNameVal.Value && uidOfv != subjectUid {\n\t\t\t\t\t\treturn errors.Errorf(\"could not insert duplicate value [%v] for predicate [%v]\",\n\t\t\t\t\t\t\tv.Value, pred.Predicate)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\tpredValue = val.Value\n\t\t\t}\n\t\t} else {\n\t\t\tpredValue = dql.TypeValFrom(pred.ObjectValue).Value\n\t\t}\n\n\t\t// Here, we check the uniqueness of the triple by comparing the result of the uniqueQuery with the triple.\n\t\tif !isEmpty(queryResult.Uids) {\n\t\t\tif len(queryResult.Uids.Uids) > 1 {","sourceCodeStart":1806,"sourceCodeEnd":1842,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/server.go#L1806-L1842","documentation":"Dgraph enforces @unique on a predicate during upsert mutations. When the mutation's value comes from a val(var) variable, verifyUnique iterates all existing UIDs holding the value and rejects the mutation if another node (different UID from the mutation subject) already stores the same value. This is the normal unique-constraint violation for value-variable mutations — Dgraph refuses to create a second node with the same value for a @unique predicate.","triggerScenarios":"An upsert mutation sets predicate P (declared @unique in schema) with object val(v) where v holds a value, and the uniquecheck query finds an existing node with that same value whose UID differs from the subject UID (edgraph/server.go:1824).","commonSituations":"Creating a second user with the same email/username in a schema like `email: string @unique @index(exact)`; concurrent signups racing for the same email; re-running a seed script that inserts records already present; syncing data from an external system that already has rows with colliding values.","solutions":["Catch the error and treat it as a business-rule violation: run a query for the existing value and return that node instead of inserting","Use an upsert block so the same value updates the existing node (blank node mapped to uid(var)) rather than inserting a duplicate","Ensure the predicate has an index (e.g. @index(exact) for strings) — the unique check requires it and it makes dedup queries cheap","If the duplicate is unintended legacy data, delete or merge the colliding nodes before re-running the mutation"],"exampleFix":"// before\nupsert(query: \"{ v as var(func: eq(email, \\\"a@b.com\\\")) }\",\n       mutation: \"{ set { _:u <email> val(v) . } }\")  // rejects if email exists elsewhere\n// after\nupsert(query: \"{ v as var(func: eq(email, \\\"a@b.com\\\")) }\",\n       mutation: \"{ set { uid(v) <email> \\\"a@b.com\\\" . uid(v) <name> \\\"A\\\" . } }\")","handlingStrategy":"try-catch","validationCode":"// Before insert, check existence:\nq := `{ q(func: eq(email, $val)) { uid } }`\nresp, _ := dg.NewTxn().Query(ctx, q)\n// if resp has nodes, update instead of insert","typeGuard":null,"tryCatchPattern":"_, err := txn.Mutate(ctx, mu)\nif err != nil && strings.Contains(err.Error(), \"could not insert duplicate value\") {\n\t// fetch existing node by value and return/merge it\n\treturn getExistingByValue(ctx, value)\n}","preventionTips":["Declare @unique with a supporting index (e.g. @index(exact)) in the schema","Prefer upsert blocks over blind inserts for unique fields","Map blank nodes to uid(var) so existing nodes are updated, not duplicated","Make signup flows idempotent: query-then-update keyed on the unique value"],"tags":["dgraph","unique-constraint","mutation","duplicate"],"backgroundTag":"unique-constraint-violation","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}