Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

RFC 9457 Problem Details for HttpApi errors

Open
#9,686 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@effect-bot is already working on this.

Since Oct 21, 2026.

  • #9706 by @effect-bot — open

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
20/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Stale
Tech stack
typescript

Research direction

Start with packages/effect/src/http-api/HttpApiError.ts and the existing HttpApi middleware, schema, OpenAPI, and client paths named in the proposal. Review linked pull request #9706 and issue #5367 before considering scope; the issue leaves package placement and decode disclosure open. Done means implementing the proposed Problem Details schema, typed errors, opt-in rendering, OpenAPI support, and client decoding while preserving the default empty-body behavior.

Written by the indexing model from the issue text.

Description

docker-made-me-do-it enhancement

Problem

RFC 9457 (application/problem+json) is the standard JSON format for HTTP API errors. HttpApi doesn't support it, and by default its errors have no body:

  • The built-in errors (HttpApiError.BadRequest, NotFound, and so on) are sent as empty responses (packages/effect/src/http-api/HttpApiError.ts:23-56).
  • When a request fails to decode, the server answers with an empty 400 (HttpApiError.ts:507). The client gets no indication of which field was wrong or why.

You can build Problem Details yourself with HttpApiMiddleware.layerSchemaErrorTransform and HttpApiSchema.asJson({ contentType }). But every project then writes its own schema, picks its own type, title and status defaults, and has to get the RFC's parsing rules right. For example, §3.1 says a member with the wrong JSON type is ignored, not rejected. #5367 asked for this in v3 and was closed with a workaround that re-encoded response bodies in a middleware. The people in that thread noted that the OpenAPI output then had to be patched as well.

Proposal

  1. A ProblemDetails value and Schema:
    • type defaults to about:blank.
    • status, title, detail and instance are optional.
    • Unknown members are kept as extensions.
    • It decodes leniently, as §3.1 requires, and encodes canonically.
    • A way to declare a typed problem: a fixed type URI with typed extension members, usable as an HttpApi error schema with the right status, media type and OpenAPI entry.
  2. An opt-in that renders HttpApi's own errors (decode failures and the built-ins) as Problem Details.
  3. HttpApiClient decodes application/problem+json responses into the declared problem type.
// names illustrative
class OutOfCredit extends ProblemDetails.Type("https://example.com/probs/out-of-credit", {
  status: 403,
  balance: Schema.Number
}) {}

HttpApiEndpoint.post("buy", "/buy", { error: OutOfCredit })

Why in Effect

HttpApi owns both the mapping from errors to responses and the OpenAPI output, so this is the one place where it can be done without post-processing bodies and patching the spec. The format is widely supported elsewhere: ASP.NET Core (AddProblemDetails), Spring (ProblemDetail), and Rust's http-api-problem crate.

Scope

In scope:

  • The value and Schema, typed problems, opt-in rendering, OpenAPI output and client decoding.

Out of scope:

  • application/problem+xml.
  • Changing the default empty-body behaviour without an opt-in.

Open questions

  • Should this live in effect/http, so it can be used without HttpApi, or in effect/http-api?
  • How much should a decode failure reveal by default? The failing path and message help clients, but they also expose details of the schema.
Dominant language
TypeScript
Stars
16.7k
Forks
808
Avg merge
10h 7m
Merged PRs (30d)
808

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Effect-TS/effect

All issues in Effect-TS/effect

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.