SDK: sanitize malformed-success HTTP decoding causes
@samuv is already working on this.
Since Sep 18, 2026.
- Dominant language
- Go
- Stars
- 152
- Forks
- 16
- Avg merge
- 14h 48m
- Merged PRs (30d)
- 536
Description
Problem
The TypeScript SDK's shared HTTP transport wraps malformed successful HTTP and SSE responses in ProtocolError, but currently retains the native JSON or protobuf decoder exception as ProtocolError.cause.
JavaScript decoder messages are runtime-dependent. Some engines may include excerpts of the rejected response in an exception message. If a malformed successful response contains sensitive material—such as a short-lived presentation URL—and an application logger captures nested error causes, that material could be copied into application logs.
This is defense-in-depth, not a demonstrated credential disclosure:
- the SDK does not automatically log these errors;
MecatlError.toJSON()already omitscause;- the observed reproduction exposed only a URL prefix, not a complete credential; and
- this concerns existing shared transport behavior rather than one server endpoint.
Raised from the non-blocking review follow-up on #1690: https://github.com/stacklok/mecatl/pull/1690#pullrequestreview-5245634245
Direction
Define one shared policy for malformed successful-response decoding at the SDK HTTP boundary:
- unary invalid-JSON and protobuf-decoding failures return the existing generic
ProtocolErrorwithout the raw decoder cause; - SSE invalid-JSON and protobuf-decoding failures follow the same rule;
- retain safe metadata such as
code,transport, HTTP status, and request ID where available; and - do not attempt best-effort string redaction of arbitrary decoder messages.
Keep this narrowly scoped. Do not change:
- non-2xx RFC 9457/server-error normalization;
- fetch/network
TransportErrorcauses; - authentication errors;
- abort and cancellation behavior; or
- stream/control lifecycle semantics.
Acceptance criteria
- A unary successful response with malformed JSON rejects with
ProtocolError,transport: "http", the HTTP status, no rawcause, and no planted response canary in its message ortoJSON()result. - A unary successful response that parses as JSON but fails descriptor/protobuf decoding has the same cause-free behavior.
- Malformed JSON and descriptor/protobuf failures in ordinary SSE data frames have the same cause-free behavior without changing streaming or cancellation semantics.
- Existing non-2xx server errors retain their typed code, request ID, status, and established cause behavior.
- Existing fetch/network and abort/cancellation tests prove their semantics are unchanged.
- The SDK error documentation and living design notes describe the malformed-success cause policy.
Compatibility
No public type or method signature changes. This intentionally narrows diagnostic detail available through ProtocolError.cause for malformed successful HTTP/SSE payloads so untrusted response content cannot cross into application logging through decoder exceptions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.