Problem #
Blob fields (a profile's avatar and banner, an image embed's image) render as a "raw JSON" textarea, even when they are optional. A blob needs a reference to a file already uploaded to the user's PDS, which nobody can type by hand. The box only invites a value that can't work, and it makes an optional field look like something to fill in.
Split out of #26, which fixed optional objects and deprecated fields but left this bullet.
Code: lib/lexicons/schema-tree.ts sends blob to the default case, so it becomes unknown and renders through UnknownField in RecordFormBuilder.tsx.
Fix direction #
- Give blobs their own node type in
schema-tree.tsinstead ofunknown.unknownalso covers cycles, depth cutoffs and missing refs, which must keep their raw JSON editor. - Collapse optional blob fields behind "+ Add ", as #26 does for optional objects. Hiding them would make an optional blob impossible to set. Once added, show the raw JSON editor with a hint that the builder can't upload files yet. A template that already holds a value for one opens expanded, so old templates stay editable.
- Required blob fields keep the raw JSON editor, with a hint that the builder can't upload files yet.
Out of scope here: uploading files. The builder makes a template that runs later, and a PDS deletes uploaded blobs that no record points to. So a file uploaded while building the template would be gone before the automation writes the record. A real blob input needs the template to keep a source (a file stored by Airglow, or a URL), and the action to upload it at run time, the way bsky-post does for link-card thumbnails with uploadBlob. That needs a design decision and gets its own issue.
Queued: the loop will work on this version of the issue.
loop:queued cid=bafyreiczknu7joeorleby2qi6sfxizrsx3tmfpuoz2iolj25ofhr6uvtjm