sveltejs / sveltejs/kit

"TypeError: str.replace is not a function" when using $app/server `read` function

Open
#14,724 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

error handling
Dominant language
JavaScript
Stars
20.8k
Forks
2.3k
Avg merge
1d 16h
Merged PRs (30d)
156

Description

Describe the bug

I am attempting to use the $app/server read function to include some large JSON files in my project and read them for use in +server.js enpoints.

I can get it to work in dev mode, but it's failing when I preview a build with adapter-node, and also when I try to deploy to netlify with adapter-netlify. In both cases, the JSON files are getting copied across to the build folder.

(Note: I am only at a prototyping phase. The code below shows the logic rather than the intented implementation, where the JSON will be filtered etc based on API requests.)

I have a lib/data folder where I'm keeping the JSON files, which includes an index.js file with code like this:

import { read } from "$app/server";

// Make Vite import the JSON files in this directory into the build
const files = import.meta.glob("./*.json", {
  query: "?url",
  import: "default",
  eager: true,
});

// Read a JSON data file from disk or return cached version
const cache = {};
export default async function(file) {
  if (cache[file]) return cache[file];

  const path = files[file];
  if (!path) return {error: 404, message: "File not found"};

  const asset = read(path);
  const data = await asset.json();
  cache[key] = data;

  return data;
}

I have a [file]/+server.js file within my routes folder to return the JSON data that looks like this:

import { json, error } from "@sveltejs/kit";
import readData from "$lib/data";

export async function GET({ params }) {
  const file = params.file;

  const data = await readData(file);
  if (data.error) error(data.error, data.message);

  return json(data);
}

When previewing my local node build I get the following server error:

file:///{my-local-path}/.svelte-kit/output/server/index.js:122
  const escaped_str = str.replace(is_attr ? escape_html_attr_regex : escape_html_regex, (match) => {
                          ^
TypeError: str.replace is not a function
    at escape_html (file:///{my-local-path}/.svelte-kit/output/server/index.js:122:27)
    at static_error_page (file:///{my-local-path}/.svelte-kit/output/server/index.js:151:58)
    at handle_fatal_error (file:///{my-local-path}/.svelte-kit/output/server/index.js:170:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async internal_respond (file:///{my-local-path}/.svelte-kit/output/server/index.js:3539:12)
    at async file:///{my-local-path}/node_modules/@sveltejs/kit/src/exports/vite/preview/index.js:199:5

Node.js v22.18.0

Running on Netlify I get a fairly similar error:

TypeError: str.replace is not a function
    at escape_html (file:///var/task/.netlify/server/index.js:121:27)
    at static_error_page (file:///var/task/.netlify/server/index.js:150:58)
    at handle_fatal_error (file:///var/task/.netlify/server/index.js:169:10)
    at async internal_respond (file:///var/task/.netlify/server/index.js:3538:12)
    at async Runtime.handler (file:///var/task/.netlify/serverless.js:305:20)

My guess is that the read function might not be looking in the right location for the file, or it might otherwise not be getting the expected response from Vite's import.meta.glob magic.

Reproduction

https://github.com/ONSdigital/els-api-poc/tree/data-loading-experiments
(Apologies. This is just my working project file. If there isn't an obvious fix based on the description above then I'll create a dedicated project to reproduce the issue.)

Logs
See above
System Info
System:
    OS: macOS 11.6.1
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
    Memory: 3.55 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
Binaries:
    Node: 22.18.0 - /Users/ahmadbarclay/.nvm/versions/node/v22.18.0/bin/node
    npm: 10.9.3 - /Users/ahmadbarclay/.nvm/versions/node/v22.18.0/bin/npm
    Deno: 2.3.3 - /Users/ahmadbarclay/.deno/bin/deno
Browsers:
    Chrome: 138.0.7204.184
    Firefox: 143.0.4
    Safari: 14.1.2
npmPackages:
    @sveltejs/adapter-netlify: ^5.2.4 => 5.2.4 
    @sveltejs/adapter-node: ^5.3.3 => 5.3.3 
    @sveltejs/kit: ^2.46.5 => 2.46.5 
    @sveltejs/vite-plugin-svelte: ^4.0.0 => 4.0.4 
    svelte: ^5.0.0 => 5.39.11 
    vite: ^5.4.4 => 5.4.20
Severity

serious, but I can work around it

Additional Information

I think my only other option is to wade into Node's native fs functions.

Contributor guide

Open the contributing guide

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.

Research direction

Start with lib/data/index.js and the [file]/+server.js endpoint in the linked reproduction branch. Reproduce the endpoint in development, adapter-node preview, and adapter-netlify deployment, then trace how $app/server read handles the import.meta.glob URL in each build. Done means the endpoint reads the JSON consistently in the affected environments without the str.replace error.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, vite
Domain
api, backend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.