{"record":{"id":"2020c7dde0361bb5","repo":"unionlabs/union","slug":"packet-not-found","errorCode":null,"errorMessage":"Packet not found","messagePattern":"Packet not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"app2/src/lib/queries/packet-details.svelte.ts","lineNumber":77,"sourceCode":"            timestamp\n            transaction_hash\n            chain {\n              universal_chain_id\n              rpc_type\n            }\n          }\n          \n        }\n      }\n    `),\n    variables: { packet_hash: packetHash },\n    refetchInterval: \"30 seconds\",\n    writeData: data => {\n      data.pipe(\n        Option.map(d => {\n          if (d.v2_packets.length === 0) {\n            // TODO: make tagged error\n            throw new Error(\"Packet not found\")\n          }\n          return d.v2_packets[0]\n        }),\n        Option.tap(packet => {\n          packetDetails.data = Option.some(packet)\n          return Option.some(packet)\n        }),\n      )\n    },\n    writeError: error => {\n      packetDetails.error = error\n    },\n  })\n","sourceCodeStart":59,"sourceCodeEnd":91,"githubUrl":"https://github.com/unionlabs/union/blob/031785bb6dc6b957c624e62bc64c184409c97d7b/app2/src/lib/queries/packet-details.svelte.ts#L59-L91","documentation":"Thrown in the writeData callback of a TanStack Query (Svelte) that polls a GraphQL v2_packets query every 30 seconds for a given packet_hash. It fires when the query succeeds but returns an empty v2_packets array, meaning the backend currently has no packet with that hash. The '// TODO: make tagged error' comment shows the authors know this generic Error conflates 'not indexed yet' with 'does not exist'.","triggerScenarios":"Querying packet details with (a) a mistyped or truncated hash, (b) a packet that was just broadcast and is not yet indexed (the throw repeats on each 30s refetch until the indexer catches up), or (c) a hash from a different network than the GraphQL endpoint serves.","commonSituations":"Fresh cross-chain transactions where the packet lands on-chain seconds before the subgraph sees it; copying a hash without the 0x prefix or with missing characters; pointing the app at testnet data while using a mainnet hash.","solutions":["Verify the hash is the full 66-character 0x-prefixed value returned by the sending transaction and belongs to the network the GraphQL endpoint indexes","If the packet was just sent, treat this as transient: the 30-second refetchInterval recovers automatically once the indexer ingests the packet","Run the v2_packets query directly in the GraphQL playground with the same packet_hash variable to confirm whether the row exists server-side","Replace the generic Error with a tagged error (per the TODO) so UI code can distinguish 'pending indexing' from 'never exists' and stop retrying"],"exampleFix":"// before\nif (d.v2_packets.length === 0) {\n  // TODO: make tagged error\n  throw new Error(\"Packet not found\")\n}\nreturn d.v2_packets[0]\n\n// after\nexport class PacketNotFoundError extends Error {\n  readonly _tag = \"PacketNotFoundError\" as const\n}\nif (d.v2_packets.length === 0) {\n  throw new PacketNotFoundError()\n}\nreturn d.v2_packets[0]","handlingStrategy":"retry","validationCode":"const isPacketHash = (h: string) => /^0x[0-9a-fA-F]{64}$/.test(h)\n\nif (!isPacketHash(packetHash)) {\n  throw new Error(`Invalid packet hash: ${packetHash}`)\n}\n// only then start the polling query","typeGuard":"const hasPacket = (d: { v2_packets: unknown[] } | undefined): d is { v2_packets: [unknown, ...unknown[]] } =>\n  (d?.v2_packets?.length ?? 0) > 0","tryCatchPattern":"try {\n  await queryClient.refetchQueries({ queryKey: [\"packetDetails\", packetHash] })\n} catch (e) {\n  if (e instanceof Error && e.message === \"Packet not found\") {\n    // transient: packet not indexed yet — keep polling, do not surface as fatal\n    return\n  }\n  throw e\n}","preventionTips":["Validate the hash format before starting the query","Treat 'not found' on a freshly broadcast transaction as pending, not fatal","Introduce a tagged error so retry/UI code can match on the specific case instead of the message string"],"tags":["graphql","indexing","data-availability","svelte-query"],"backgroundTag":null,"analyzedSha":"031785bb6dc6b957c624e62bc64c184409c97d7b","analyzedAt":"2026-08-16T06:24:09.996Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}