Skip to content

fix(providers): fold fullwidth header values instead of failing the request - #896

Merged
vastsa merged 2 commits into
mainfrom
fix/provider-header-latin1
Sep 22, 2026
Merged

vastsa merged 2 commits into
mainfrom
fix/provider-header-latin1

Conversation

@vastsa

@vastsa vastsa commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • A fullwidth character in a provider custom header or API key (for example 0) made undici throw TypeError: Cannot convert argument to a ByteString ... greater than 255 before the request left. That is the failure reported from the model config panel and the send box in [Bug] 全角字符问题 #868.
  • Fullwidth forms (U+FF01–U+FF5E) and the ideographic space fold onto ASCII on read and on write. What still cannot travel in an HTTP header is refused at save with the character and its index, and dropped from a stored or synced map so an old row cannot fail a turn or a whole revision.

fixes #868

Test plan

  • cargo test -p host-core --locked fullwidth (2 passed; host-core test binary compiled)
  • packages/shared header-value.test.ts (13 passed)
  • packages/agent-runtime provider-headers.test.ts (13 passed)
  • apps/desktop provider-form-layout.test.mjs (22 passed)
  • pnpm check:pr-base
  • E2E-005G stays Documented, not run

Copilot AI lite review requested due to automatic review settings September 22, 2026 18:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…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
vastsa force-pushed the fix/provider-header-latin1 branch from e5ef757 to 21af7d6 Compare September 22, 2026 18:15
@vastsa
vastsa merged commit dc5e1fb into main Sep 22, 2026
4 checks passed
@vastsa
vastsa deleted the fix/provider-header-latin1 branch September 24, 2026 01:54
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.

[Bug] 全角字符问题

2 participants