Thanks to visit codestin.com
Credit goes to github.com

Skip to content

set.headers['content-type'] is ignored when returning a string — node adapter overrides with text/plain #56

@xpr0gamers

Description

@xpr0gamers

Bug Report

Description

When using the @elysiajs/node adapter, manually setting set.headers['content-type'] inside a route handler has no effect when the handler returns a string. The adapter always overrides the content-type with text/plain; charset=UTF-8, ignoring the value set via set.headers.

This works correctly with the native Bun runtime (no adapter).

Related: elysiajs/elysia#1299 (same root cause, different return type)


Minimal Reproduction

import { Elysia } from 'elysia';
import { node } from '@elysiajs/node';

const app = new Elysia({ adapter: node() })
  .get('/xml', ({ set }) => {
    set.headers['content-type'] = 'text/xml';
    return '<root><item>hello</item></root>';
  })
  .listen(3000);

Request:

GET http://localhost:3000/xml

Actual response header:

content-type: text/plain; charset=UTF-8

Expected response header:

content-type: text/xml

Workaround

Return a Response object directly instead of relying on set.headers:

.get('/xml', () => {
  return new Response('<root><item>hello</item></root>', {
    headers: { 'content-type': 'text/xml' },
  });
})

Environment

elysia 1.4.25
@elysiajs/node 1.4.5
Node.js v24.8.0
Platform macOS (darwin)

Additional Context

Discovered while writing Vitest-based integration tests for a library that uses the Elysia OData plugin. The tests run under Node.js (via Vitest) and require the node() adapter. With set.headers, the content-type was silently overridden. Switching to new Response(...) fixed the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions