Skip to content

Accept the data model's unpadded base64 in $bytes#48

Merged
germ-mark merged 2 commits into
mainfrom
fix/bytes-nopad-base64
Jul 15, 2026
Merged

Accept the data model's unpadded base64 in $bytes#48
germ-mark merged 2 commits into
mainfrom
fix/bytes-nopad-base64

Conversation

@germ-mark

@germ-mark germ-mark commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

The atproto data model serializes bytes as base64 without padding, but response decoding used JSONDecoder's default .base64 Data strategy, which rejects unpadded input. Any PDS that stores records as CBOR re-emits bytes unpadded (verified against both blacksky's rsky and bsky's own PDS), so records failed to decode whenever the byte length wasn't a multiple of 3; lengths that align to 4 base64 chars (e.g. a 33-byte anchor key) worked by luck, which made the failure look intermittent. The dual-slot PQ keyPackage (~3.4 KB) always lands on the misaligned case.

The tolerance is a decoder option, not a property of the type: JSONDecoder.atproto (via dataDecodingStrategy.atprotoBase64) accepts both unpadded (spec) and padded (previously written) forms for every Data field, and XRPC response parsing reads through it; a default JSONDecoder keeps Foundation's strict behavior. Atproto.Primitive.Bytes encodes the spec's unpadded form. Includes a changeset (patch). App-side counterpart: germ-network/germDM-ios-refresh#497.

🤖 Generated with Claude Code

Synthesized Codable used JSONDecoder's .base64 Data strategy, which
requires padding the atproto data model omits — so records re-serialized
by a spec-compliant PDS (e.g. blacksky's rsky) failed to decode whenever
the byte length wasn't a multiple of 3. Decode now tolerates both forms
and encoding emits the spec's unpadded form.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d2d0807

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@germ-network/atprototypes Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Move the padding tolerance off Bytes' init(from:) onto the decoder:
JSONDecoder.atproto (dataDecodingStrategy .atprotoBase64) accepts the
data model's unpadded form for EVERY Data field, not just $bytes, and
XRPC response parsing reads through it. A default JSONDecoder keeps
Foundation's strict behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@germ-mark germ-mark merged commit 5c2a9e8 into main Jul 15, 2026
8 checks passed
@germ-mark germ-mark deleted the fix/bytes-nopad-base64 branch July 15, 2026 20:02
@github-actions github-actions Bot mentioned this pull request Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant