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.dart — bucket=tag-metadata, key=.fula/tags/<userId>.json
lib/core/services/nft_service.dart — bucket=nft-metadata, key=.fula/nfts/<userId>.json (or similar)
lib/core/services/website_service.dart — bucket=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:
- 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("")).
- 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).
- Forest format case —
loadForest 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
- Sign in to FxFiles on a real device as a user who has used the tagging / NFT / generated-websites features.
- Watch
flutter run log on app launch (or on reinitializeFulaClient).
- The three "Forest load for X failed: …serialization error: expected value at line 1 column 1" lines fire on every restart.
Suggested investigation order
- 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.
- 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.
- 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.
Symptom
Loading the metadata-only buckets fails consistently with a serialization error, while the bucket itself loads successfully:
Pattern: the
serialization error: expected value at line 1 column 1text format is the classicserde_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 byTagStorageService,NftService, andWebsiteService.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.dart—bucket=tag-metadata,key=.fula/tags/<userId>.jsonlib/core/services/nft_service.dart—bucket=nft-metadata,key=.fula/nfts/<userId>.json(or similar)lib/core/services/website_service.dart—bucket=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 vialistObjectsrather than a singletondownloadObject+ JSON decode.The hypothesis is one of:
fula-clientreturns 404 / empty bytes. FxFiles passes that intojsonDecodewithout checking, andserde_json-style error surfaces (probably wrapped fromJsonDecoder.convert("")).jsonDecodethe raw ciphertext before decryption (decryption layer order wrong somewhere).loadForestitself 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 errorso the wrapping layer thinks it's an encryption-stage failure. That points at (2) or (3) rather than (1) — but the error format isserde_json-like, so something in the chain IS doing JSON.What we know is NOT the cause
master DNS-failerrors AND these serialization errors side by side in the same logs — they're distinct categories).functionland/fula-api#N). Walkable-v8 affects offline-walking the HAMT; these three buckets fail to load AT ALL (even online).ehsan@fx.landand uses all three features (tags, NFTs, generated websites) on the device.Reproducer
flutter runlog on app launch (or onreinitializeFulaClient).Suggested investigation order
Encryption error: serialization errorstring. Grep bothfula-client(Rust) and FxFiles (Dart). The wrappingEncryption error:suggests aClientError::Encryption(...)variant on the Rust side wrapping an inner error whoseDisplayproduces the JSON-style message.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.