unionlabs/union · error · Error

Not a MoveObject

Error message

Not a MoveObject

What it means

readUcs03Port fetches the UCS03 port object on Sui with { showContent: true } and requires res.data.content.dataType === "moveObject" before casting fields to the Port shape. If the id resolves to no data (missing object), a package, or a wrapped/deleted object, the guard fails and throws.

Source

Thrown at ts-sdk-sui/src/internal/zkgmClient.ts:42

type HexAddr = `0x${string}`
const base58ToHex = (s: string): Hex => toHex(bs58.decode(s)) as Hex

interface Port {
  id: { id: HexAddr }
  _module_address: HexAddr
  data: HexAddr
}

export const readUcs03Port = (client: SuiClient, portId: string) =>
  Effect.tryPromise({
    try: () =>
      client.getObject({
        id: portId,
        options: { showContent: true },
      }).then(async res => {
        if (res.data?.content?.dataType !== "moveObject") {
          throw new Error("Not a MoveObject")
        }

        const f = res.data.content.fields as unknown as Port

        return {
          ucs03Address: f._module_address,
          module: "zkgm",
          relayStoreId: f.data,
        }
      }),
    catch: error => error,
  })

export const fromWallet = (
  opts: { client: Sui.Sui.PublicClient; wallet: Sui.Sui.WalletClient },
): Client.ZkgmClient =>
  Client.make((request, signal, fiber) =>
    Effect.gen(function*() {

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Look the portId up in the Sui explorer for the same network and confirm the object exists
  2. Run `sui client object <portId>` and verify the output shows dataType: moveObject
  3. Align the SDK/client network with the deployed port addresses in config

Example fix

// before
if (res.data?.content?.dataType !== "moveObject") {
  throw new Error("Not a MoveObject")
}

// after
const content = res.data?.content
if (!content || content.dataType !== "moveObject") {
  throw new Error(
    `UCS03 port ${portId} is not a MoveObject (dataType=${content?.dataType ?? "missing"})`,
  )
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check the object exists and is a Move object before reading the port
const res = await client.getObject({ id: portId, options: { showContent: true } })
const ok = res.data?.content?.dataType === "moveObject"
if (!ok) console.warn(`Port ${portId} missing or not a MoveObject on this network`)

Type guard

const isMoveObjectContent = (
  c: { dataType?: string } | undefined,
): c is { dataType: "moveObject"; fields: Record<string, unknown> } =>
  c?.dataType === "moveObject"

Try / catch

const result = await Effect.runPromiseExit(readUcs03Port(client, portId))
if (Exit.isFailure(result)) {
  // verify the id in the explorer / sui client object <portId> before retrying
  throw new Error(`UCS03 port ${portId} not readable — check network and object id`)
}

Prevention

When it happens

Trigger: A portId that is wrong for the network being queried (testnet/mainnet mixup); the port object not yet created on an early-stage chain; the object deleted or wrapped since deployment; a truncated/malformed object id.

Common situations: Hardcoded per-network port addresses drifting out of sync; config shipped before the port contract was deployed; pointing the SDK at a different RPC network than the addresses assume.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/4dace98e3adc8938. Report an issue: GitHub.