{"record":{"id":"debc961f5365a95a","repo":"dgraph-io/dgraph","slug":"persistedquerynotfound","errorCode":null,"errorMessage":"PersistedQueryNotFound","messagePattern":"PersistedQueryNotFound","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgraph/graphql.go","lineNumber":92,"sourceCode":"\t\treturn err\n\t}\n\n\ttype shaQueryResponse struct {\n\t\tMe []struct {\n\t\t\tPersistedQuery string `json:\"dgraph.graphql.p_query\"`\n\t\t} `json:\"me\"`\n\t}\n\n\tshaQueryRes := &shaQueryResponse{}\n\tif len(storedQuery.Json) > 0 {\n\t\tif err := json.Unmarshal(storedQuery.Json, shaQueryRes); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif len(shaQueryRes.Me) == 0 {\n\t\tif query == \"\" {\n\t\t\treturn errors.New(\"PersistedQueryNotFound\")\n\t\t}\n\t\tif match, err := hashMatches(query, sha256Hash); err != nil {\n\t\t\treturn err\n\t\t} else if !match {\n\t\t\treturn errors.New(\"provided sha does not match query\")\n\t\t}\n\n\t\treq = &Request{\n\t\t\treq: &api.Request{\n\t\t\t\tMutations: []*api.Mutation{\n\t\t\t\t\t{\n\t\t\t\t\t\tSet: []*api.NQuad{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSubject:     \"_:a\",\n\t\t\t\t\t\t\t\tPredicate:   \"dgraph.graphql.p_query\",\n\t\t\t\t\t\t\t\tObjectValue: &api.Value{Val: &api.Value_StrVal{StrVal: join}},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/graphql.go#L74-L110","documentation":"In ProcessPersistedQuery, a request carrying only an extensions.persistedQuery.sha256Hash but no query string is resolved by looking the hash up in the stored persisted queries; if the lookup returns no rows, the server returns PersistedQueryNotFound. This is the standard Apollo persisted-query miss, indicating the client cached hash isn't stored on the server.","triggerScenarios":"POST/GET with extensions {\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"...\"}} and no `query` field, when the sha256Hash doesn't match any stored PersistedQuery node for that user.","commonSituations":"Client (Apollo Link PersistedQueries) sends hash from cache but server data was wiped/restored (e.g. after DropAll); hash registered in a different namespace or under a different user; server restarted with fresh data; query was never registered because the first request failed.","solutions":["Send the full query text along with the sha256Hash once — the server verifies the hash and registers the persisted query (this is the automatic Apollo retry path)","Verify the hash was computed over the exact query string (whitespace-sensitive) with sha256, not md5 or a normalized variant","Re-register the persisted query (issue the query+hash pair) after any DropAll/restore of the data","Check the GraphQL persisted-query registration mutation result for errors on the initial request"],"exampleFix":"// before: hash-only request that misses\n{\"extensions\":{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"abc...\"}}}\n// after: include query to self-register on miss\n{\"query\":\"query Me { me { name } }\",\"extensions\":{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"<sha256(query)>\"}}}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function runPersisted(sha, buildQuery) {\n  try {\n    return await gql({ extensions: { persistedQuery: { version: 1, sha256Hash: sha } } })\n  } catch (e) {\n    if (String(e.message).includes('PersistedQueryNotFound')) {\n      // standard Apollo recovery: resend full query + hash to re-register\n      return gql({ query: buildQuery(), extensions: { persistedQuery: { version: 1, sha256Hash: sha } } })\n    }\n    throw e\n  }\n}","preventionTips":["Configure Apollo PersistedQueryLink with automatic fallback (default behavior) — never disable useGETForHashedQueries/retry logic blindly","Re-register persisted queries after DropAll/restore of the GraphQL data","Use the same hashing normalization across all client versions"],"tags":["graphql","persisted-queries","apollo","cache-miss"],"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"}