#1972·elysia

Elysia 2: guard-level detail (OpenAPI tags) is dropped for routes with their own hook

Author: netsvetochCreated Aug 19, 2026Updated Aug 19, 2026

What version of Elysia is running?

2.0.0-exp.64 (with @elysiajs/openapi 2.0.0-exp.1)

What platform is your computer?

Linux x86_64

What environment are you using

Bun 1.3.14

Are you using dynamic mode?

No

What steps can reproduce the bug?

typescript
import { Elysia, t } from "elysia";
import { openapi } from "@elysiajs/openapi";

const app = new Elysia()
  .use(openapi())
  .guard({ detail: { tags: ["Admin"] } }, (app) =>
    app
      .get("/plain", () => "ok")
      .post(
        "/with-body",
        { body: t.Object({ name: t.String() }) },
        ({ body }) => body,
      ),
  );

const spec = await app
  .handle(new Request("http://localhost/openapi/json"))
  .then((r) => r.json());

console.log(spec.paths["/plain"].get.tags);      // ["Admin"]  ✅
console.log(spec.paths["/with-body"].post.tags); // undefined  ❌

What is the expected behavior?

The guard's detail should apply to every route registered inside the guard scope, including routes that declare their own hook (body, query, params, ...). The OpenAPI operation for POST /with-body should contain tags: ["Admin"].

What do you see instead?

Routes without their own hook object inherit the guard's detail correctly, but routes with a hook lose it entirely: their hooks.detail ends up undefined, so @elysiajs/openapi (const operation = { ...hooks.detail }) emits no tags for them.

The guard chain is merged in composeRouteHook via mergeHook (dist/utils.mjs), which merges schemas and lifecycle hooks but never merges detail.

Additional information

  • Related: #1947 — constructor-level tags (new Elysia({ tags })) are not propagated to routes at all. This report is about the guard path, which partially works but silently drops detail for routes with their own hooks.
  • Workaround: set detail.tags explicitly on every route.

Have you try removing the node_modules and bun.lockb and try again yet?

Reproduced on a clean install of [email protected].