store: refuse oversized filename components before writing - #35
Open
eordano wants to merge 1 commit into
Open
Conversation
eordano
force-pushed
the
fix/loud-oversized-write
branch
from
July 31, 2026 16:45
8cd4a80 to
143d220
Compare
Filename components over NAME_MAX (255 bytes) fail with the raw
filesystem error (ENAMETOOLONG; "os error 3"/"os error 123" on
Windows) from deep inside a conversion, long after the doomed name was
chosen. Only unbounded dev-lane ids get this long: b64-<base64 of a
local path> pseudo-hashes from the sdk-commands preview server pass 255
bytes once the encoded path reaches ~190 characters.
Names derived through fs_safe_component are already collapsed to a
bounded digest, but two writers must keep the incoming name verbatim to
preserve its round-trip: the raw content store (files keyed by cid) and
the CLI corpus lane (bundles keyed by served name). Add a shared guard,
FS_WRITE_COMPONENT_MAX_BYTES = 240 (NAME_MAX minus headroom for the
.tmp.{pid}.{seq} suffixes of atomic writes), and refuse the write up
front with the offending name and its length, before any directory or
sibling file is created.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
eordano
force-pushed
the
fix/loud-oversized-write
branch
from
July 31, 2026 17:45
143d220 to
bc414cd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Filename components over NAME_MAX (255 bytes on every supported filesystem) can never be written, but today the attempt fails with the raw filesystem error —
ENAMETOOLONG, oros error 3/os error 123on Windows — surfaced from deep inside a conversion, far from where the doomed name was chosen. Observed on a Windows box while verifying #33:Only unbounded dev-lane ids get this long:
b64-<base64 of absolute local path>pseudo-hashes from the sdk-commands preview server pass 255 bytes once the encoded path reaches ~190 characters. Serving-side names in the 200–255 band are already handled by the #33 collapse; names beyond 255 cannot be stored at all, by anyone.Fix
Names derived through
fs_safe_componentare already collapsed to a bounded digest. Two writers must keep the incoming name verbatim to preserve its round-trip, and now refuse loudly at the point of intent:LocalContentStore::write— raw content files keyed by cidmanifest::write_scene— CLI corpus lane, bundles keyed by served name (all names vetted before anything is written, so a refusal leaves no partial output)Shared guard:
naming::ensure_writable_componentwithFS_WRITE_COMPONENT_MAX_BYTES = 240(NAME_MAX minus headroom for the.tmp.{pid}.{seq}suffixes of atomic writes). The error tells the user what to do about it and names the failed name in full — for ab64-pseudo-hash that is the encoded path itself:The JIT lane degrades exactly as before on a refused content download (glb omitted from the manifest, non-zero exitCode) — but the log now states the actual cause.
Testing
naming::tests::ensure_writable_component_boundary— 240 passes, 241 refuses with the failed name in the message.local_store::tests::write_refuses_oversized_cid_loudly— oversized cid refused before any directory is created; in-limit cid still writes.manifest::tests::write_scene_refuses_oversized_names_before_writing— oversized entity id and oversized bundle name both refused with no partial output.🤖 Generated with Claude Code