Skip to content

Cluster B: serialization error on tag-metadata / nft-metadata / website-metadata bucket loads #5

@ehsan6sha

Description

@ehsan6sha

Symptom

Loading the metadata-only buckets fails consistently with a serialization error, while the bucket itself loads successfully:

Forest load for tag-metadata failed: AnyhowException(Encryption error: serialization error: expected value at line 1 column 1)
Failed to restore tags from cloud: FulaApiException: Failed to download object: AnyhowException(Encryption error: serialization error: expected value at line 1 column 1)

Forest load for nft-metadata failed: AnyhowException(Encryption error: serialization error: expected value at line 1 column 1)
NftService: restoreFromCloud error: ...

Forest load for website-metadata failed: AnyhowException(Encryption error: serialization error: expected value at line 1 column 1)
Failed to restore website generations from cloud: ...

Pattern: the serialization error: expected value at line 1 column 1 text format is the classic serde_json "unexpected leading byte" — i.e., something tried to JSON-decode a body that is not JSON (likely empty / HTML 404 page / ciphertext).

Reproduces deterministically on fula_client 0.5.2, with master either reachable or DNS-unreachable. Other buckets in the same app session (fula-metadata, face-metadata, images, walkable-v8-test-…) load without this error. The error is specific to the three JSON-singleton-file buckets used by TagStorageService, NftService, and WebsiteService.

What these three services do differently from other buckets

Each of them stores a single JSON file keyed by user id:

  • lib/core/services/tag_storage_service.dartbucket=tag-metadata, key=.fula/tags/<userId>.json
  • lib/core/services/nft_service.dartbucket=nft-metadata, key=.fula/nfts/<userId>.json (or similar)
  • lib/core/services/website_service.dartbucket=website-metadata, key=.fula/websites/<userId>.json (or similar)

In contrast, the buckets that load fine (images, face-metadata, fula-metadata) store many files keyed under arbitrary user paths, and FxFiles consumes them via listObjects rather than a singleton downloadObject + JSON decode.

The hypothesis is one of:

  1. Empty body case — the singleton JSON file has never been uploaded for this user. fula-client returns 404 / empty bytes. FxFiles passes that into jsonDecode without checking, and serde_json-style error surfaces (probably wrapped from JsonDecoder.convert("")).
  2. Bytes-as-JSON case — the SDK returns AEAD ciphertext successfully but FxFiles tries to jsonDecode the raw ciphertext before decryption (decryption layer order wrong somewhere).
  3. Forest format caseloadForest itself surfaces this error pattern when the forest CBOR fails some inner decode that's wrapped in a generic "serialization error" string by an upstream layer.

The error message says Encryption error: serialization error so the wrapping layer thinks it's an encryption-stage failure. That points at (2) or (3) rather than (1) — but the error format is serde_json-like, so something in the chain IS doing JSON.

What we know is NOT the cause

  • It's not a master-unreachable error (the user observed both master DNS-fail errors AND these serialization errors side by side in the same logs — they're distinct categories).
  • It's not a walkable-v8 lazy-migration issue (filed separately as functionland/fula-api#N). Walkable-v8 affects offline-walking the HAMT; these three buckets fail to load AT ALL (even online).
  • It's not user-data-shape: the user is signed in to ehsan@fx.land and uses all three features (tags, NFTs, generated websites) on the device.

Reproducer

  1. Sign in to FxFiles on a real device as a user who has used the tagging / NFT / generated-websites features.
  2. Watch flutter run log on app launch (or on reinitializeFulaClient).
  3. The three "Forest load for X failed: …serialization error: expected value at line 1 column 1" lines fire on every restart.

Suggested investigation order

  1. Identify which layer emits the Encryption error: serialization error string. Grep both fula-client (Rust) and FxFiles (Dart). The wrapping Encryption error: suggests a ClientError::Encryption(...) variant on the Rust side wrapping an inner error whose Display produces the JSON-style message.
  2. Once found, log the raw bytes that were passed to whatever decoder produced the error. If empty / HTML / unrelated → it's the "no singleton file yet" case. Should be a graceful "no data found" branch in FxFiles or fula-client, not a hard error surfaced to the user.
  3. If the bytes are AEAD ciphertext → there's a decode-before-decrypt ordering bug somewhere.

Why this is unrelated to the offline-walkability work

This bug is reproducible with master fully reachable (the user's logs show it firing both online and offline). It is a separate code path from the v7→v8 HAMT migration. The two issues should be tracked independently — fixing one does not fix the other.

Not blocking

The three affected services degrade gracefully — FxFiles logs the error and continues. Tags / NFTs / website generations from prior sessions are persisted locally (Hive) so the user doesn't lose data. Cloud restore for these three is degraded, but the rest of the app works.

Acceptance: log line Forest load for tag-metadata failed: … does NOT appear after the fix. Same for nft-metadata and website-metadata.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions