fix(providers): fold fullwidth header values instead of failing the request - #896
Merged
Merged
Conversation
…equest A provider's custom header value holding a fullwidth character made undici throw `TypeError: Cannot convert argument to a ByteString ... greater than 255` before the request left: the value reached `Headers.set`, which takes a ByteString. The report was `0` (U+FF10) at index 7. Only rows created after custom headers shipped (v0.14.0) could show it, so the same configuration looked healthy on an older build. - `packages/shared/src/header-value.ts` folds the fullwidth block (U+FF01–U+FF5E) and the ideographic space (U+3000) onto ASCII, then trims, then requires HTAB, printable ASCII or the Latin-1 supplement. A full NFKC pass is deliberately not used: it rewrites halfwidth katakana into U+30A2 plus combining marks, which still cannot travel. One rule, two engines — `crates/host-core/src/providers/validation.rs` mirrors it, and both count the reported index in the units undici names. - The three boundaries fail differently on purpose. The editor's save refuses an unusable row with `HEADERS_INVALID` naming the character and its index; a stored map folds on read and drops what cannot travel, so a store written before the rule cannot fail a turn; a sync bundle is folded and dropped before it is deserialized (`retain_storable_headers`), so a row a peer on an older build still carries cannot fail a whole revision. `config_headers` and the new helper share one implementation. - Provider API keys fold on both sides (a key is signed into `Authorization` or `x-api-key`) but are not refused at save, because some auth kinds do not put the key in a header. - The Advanced editor says next to the rows when a value will be folded and when it will be refused, and only for rows that will actually be persisted. Verification: cargo test -p host-core 637 passed; packages/shared 968 passed; packages/agent-runtime 958 passed; packages/i18n 25 passed; apps/desktop 2625 passed and `tsc --noEmit` clean; docs check:locales (80 pairs) and check:docs (508 pages); check:pr-base. E2E-005G carries the packaged journey and stays Documented, not run. Specs: `03-runtime/12-provider-config-schema.md` (§headers, §validation), ADR 0178, decisions log D619, E2E-005G.
D619 is already the copied-formula decision on main, so this record takes the next free id. rustfmt the lines the fold added.
vastsa
force-pushed
the
fix/provider-header-latin1
branch
from
September 22, 2026 18:15
e5ef757 to
21af7d6
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.
Summary
0) made undici throwTypeError: Cannot convert argument to a ByteString ... greater than 255before the request left. That is the failure reported from the model config panel and the send box in [Bug] 全角字符问题 #868.fixes #868
Test plan
cargo test -p host-core --locked fullwidth(2 passed; host-core test binary compiled)packages/sharedheader-value.test.ts(13 passed)packages/agent-runtimeprovider-headers.test.ts(13 passed)apps/desktopprovider-form-layout.test.mjs(22 passed)pnpm check:pr-base