{"record":{"id":"ca36fbd4770bccf1","repo":"dgraph-io/dgraph","slug":"same-sha-returned-d-queries","errorCode":null,"errorMessage":"same sha returned %d queries","messagePattern":"same sha returned (.+?) queries","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"edgraph/graphql.go","lineNumber":131,"sourceCode":"\t\t\t\t\t\t\t\tObjectValue: &api.Value{Val: &api.Value_StrVal{\n\t\t\t\t\t\t\t\t\tStrVal: \"dgraph.graphql.persisted_query\"}},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCommitNow: true,\n\t\t\t},\n\t\t\tdoAuth: NoAuthorize,\n\t\t}\n\n\t\tctx := context.WithValue(ctx, IsGraphql, true)\n\t\t_, err := (&Server{}).doQuery(ctx, req)\n\t\treturn err\n\n\t}\n\n\tif len(shaQueryRes.Me) != 1 {\n\t\treturn fmt.Errorf(\"same sha returned %d queries\", len(shaQueryRes.Me))\n\t}\n\n\tgotQuery := \"\"\n\tif len(shaQueryRes.Me[0].PersistedQuery) >= 64 {\n\t\tgotQuery = shaQueryRes.Me[0].PersistedQuery[64:]\n\t}\n\n\tif len(query) > 0 && gotQuery != query {\n\t\treturn errors.New(\"query does not match persisted query\")\n\t}\n\n\tgqlReq.Query = gotQuery\n\treturn nil\n\n}\n\nfunc hashMatches(query, sha256Hash string) (bool, error) {\n\thasher := sha256.New()","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/graphql.go#L113-L149","documentation":"After storing a new persisted query, ProcessPersistedQuery reads it back with a query on the sha256; it expects exactly one row. If len(shaQueryRes.Me) != 1 (0 or >1), it returns 'same sha returned %d queries'. This catches duplicate or missing stored entries for the same hash — the read-back isn't visible yet or duplicate hash nodes exist.","triggerScenarios":"First-time registration of a persisted query (query+hash pair processed, stored via mutation, then queried back) when the read returns 0 rows (eventual visibility/timing, wrong namespace context) or more than 1 row (duplicate PersistedQuery nodes for the same hash).","commonSituations":"Racing concurrent first requests that each try to register the same hash, creating duplicates; DropAll/restore leaving stale duplicates; the read-back query running against a different namespace than the write.","solutions":["Retry the request; concurrent duplicate registration usually resolves on subsequent attempts","Deduplicate stored PersistedQuery nodes for that hash (query all matching, keep one, delete extras)","Ensure all requests use the same namespace so reads/writes hit the same persisted-query records","Serialize initial client start-up (avoid many goroutines firing the same first query+hash simultaneously)"],"exampleFix":"// before: N workers each register the same query at cold start\nworkers.forEach(w => w.run(initialQuery))\n// after: register once, share result\nconst ready = registerPersistedQuery(initialQuery, hash) // tolerate PersistedQueryNotFound/duplicate\nworkers.forEach(w => ready.then(() => w.run(initialQuery)))","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function registerOnce(query, hash, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await gql({ query, extensions: { persistedQuery: { version: 1, sha256Hash: hash } } })\n    } catch (e) {\n      if (/same sha returned/.test(e.message) && i < attempts - 1) {\n        await new Promise(r => setTimeout(r, 50 * 2 ** i))\n        continue\n      }\n      throw e\n    }\n  }\n}","preventionTips":["Throttle concurrent first-requests at cold start so only one client registers a given hash","Deduplicate PersistedQuery nodes per hash if duplicates appear (Ratel query on the sha)","Keep all clients in the same namespace so read-back sees the stored query"],"tags":["graphql","persisted-queries","race-condition","dedup"],"backgroundTag":"persisted-query-not-found","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}