• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

valkyrjaio / valkyrja-ts / 30324890379 / 1
100%
26.x: 100%

Build:
DEFAULT BRANCH: 26.x
Ran 28 Jul 2026 03:04AM UTC
Files 302
Run time 9s
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

28 Jul 2026 03:04AM UTC coverage: 100.0%. Remained the same
30324890379.1

push

github

web-flow
[Http] Merge added header values instead of overriding the existing header (#90)

# Description

`HeaderCollection::withAddedHeaders()` **overrode** an existing header
of the same
name instead of merging its values into it. PHP — the reference
implementation —
merges: `addHeader()` keeps the existing header and appends the incoming
values
via `withAddedValues()`, and only stores the header as-is when the name
is absent.

The TypeScript port instead routed `withAddedHeaders()` through the same
`setHeadersOnCollection()` helper that backs `withHeaders()`, whose
whole job is
to *replace*. So "added" and "set" behaved identically, and every value
already
held under that name was silently dropped.

This is not only a header-line fidelity concern — it loses data through
a public API:

- **`Response::withCookie()`** builds a `SetCookie` header and passes it
to
`withAddedHeaders()`. Because every cookie normalizes to the same
`set-cookie`
name, **a second `withCookie()` call replaced the first**, so a response
could
only ever emit one cookie. `withoutCookie()` has the same shape and the
same
  defect.
- Any caller appending to a multi-value header (`Accept`,
`Cache-Control`,
  `Vary`) lost the prior values.

`Message::injectHeader()` already implements the merge semantics by
hand, which
is a strong hint the collection was expected to do it — that helper
exists to work
around this very gap.

Found while porting the PHP message-mapping fidelity tests

([valkyrja-php#932](https://github.com/valkyrjaio/valkyrja-php/pull/932))
to
TypeScript; the two assertions that pin PHP's merge semantics failed
against the
TypeScript port. That is exactly the shift-left those tests are for.

Sibling PRs:

- **TypeScript tests** — valkyrjaio/valkyrja-ts#91 (the mapping tests
that
  caught this; two of its assertions go green once this merges)
- **PHP reference** —
[valkyrja-php#932](https://github.com/valkyrjaio/valkyrja-php/pull/932)

Coverage stays at **100%** (line and branch... (continued)

1587 of 1587 branches covered (100.0%)

Branch coverage included in aggregate %.

3473 of 3473 relevant lines covered (100.0%)

25.03 hits per line

Source Files on job 30324890379.1
  • Tree
  • List 302
  • Changed 1
  • Source Changed 1
  • Coverage Changed 1
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Build 30324890379
  • 5b52c6a8 on github
  • Prev Job for on 26.x (#30322573145.1)
  • Next Job for on 26.x (#30325155504.1)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc