[Bug]: npx @actual-app/sync-server doesn't serve http page (NotFoundError) #2427

Closed
opened 2026-02-28 20:13:33 -06:00 by GiteaMirror · 4 comments
Owner

Originally created by @gediminasel on GitHub (Aug 28, 2025).

Verified issue does not already exist?

  • I have searched and found no existing issue

What happened?

I wanted to run Actual server with pnpx @actual-app/sync-server.

Opening http://localhost:5006/ shows:

NotFoundError: Not Found
    at createHttpError (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/send@1.2.0/node_modules/send/index.js:861:12)
    at SendStream.error (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/send@1.2.0/node_modules/send/index.js:168:31)
    at SendStream.pipe (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/send@1.2.0/node_modules/send/index.js:468:14)
    at sendfile (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/express@5.1.0/node_modules/express/lib/response.js:1000:8)
    at ServerResponse.sendFile (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/express@5.1.0/node_modules/express/lib/response.js:409:3)
    at file:///home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/@actual-app+sync-server@25.8.0/node_modules/@actual-app/sync-server/build/src/app.js:114:44
    at Layer.handleRequest (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/lib/layer.js:152:17)
    at next (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/lib/route.js:157:13)
    at Route.dispatch (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/lib/route.js:117:3)
    at handle (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/index.js:435:11)

I tested and the same happens with npx @actual-app/sync-server.

How can we reproduce the issue?

pnpx @actual-app/sync-server

Open http://localhost:5006/

Where are you hosting Actual?

Other

What browsers are you seeing the problem on?

Chrome

Operating System

Linux

Originally created by @gediminasel on GitHub (Aug 28, 2025). ### Verified issue does not already exist? - [x] I have searched and found no existing issue ### What happened? I wanted to run Actual server with `pnpx @actual-app/sync-server`. Opening http://localhost:5006/ shows: ``` NotFoundError: Not Found at createHttpError (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/send@1.2.0/node_modules/send/index.js:861:12) at SendStream.error (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/send@1.2.0/node_modules/send/index.js:168:31) at SendStream.pipe (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/send@1.2.0/node_modules/send/index.js:468:14) at sendfile (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/express@5.1.0/node_modules/express/lib/response.js:1000:8) at ServerResponse.sendFile (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/express@5.1.0/node_modules/express/lib/response.js:409:3) at file:///home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/@actual-app+sync-server@25.8.0/node_modules/@actual-app/sync-server/build/src/app.js:114:44 at Layer.handleRequest (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/lib/layer.js:152:17) at next (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/lib/route.js:157:13) at Route.dispatch (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/lib/route.js:117:3) at handle (/home/gedutis/.cache/pnpm/dlx/gnkhl2lnbugfok5lbqpmqjewza/198f29c3910-2bf1a/node_modules/.pnpm/router@2.2.0/node_modules/router/index.js:435:11) ``` I tested and the same happens with `npx @actual-app/sync-server`. ### How can we reproduce the issue? `pnpx @actual-app/sync-server` Open http://localhost:5006/ ### Where are you hosting Actual? Other ### What browsers are you seeing the problem on? Chrome ### Operating System Linux
GiteaMirror added the bug label 2026-02-28 20:13:33 -06:00
Author
Owner

@gediminasel commented on GitHub (Aug 28, 2025):

I'm pretty sure this happens because npx and pnpx install packages into hidden (dot) directory (.cache), which is not served by res.sendFile (and maybe express.static?) by default.

Changing 23f1bae7db/packages/sync-server/src/app.ts (L146-L149) to

    app.use(express.static(config.get('webRoot'), { index: false, dotfiles:'allow' }));
    app.get('/{*splat}', (req, res) => res.sendFile(config.get('webRoot') + '/index.html', {dotfiles: 'allow'}));

makes the server work as expected.

@gediminasel commented on GitHub (Aug 28, 2025): I'm pretty sure this happens because `npx` and `pnpx` install packages into hidden (dot) directory (`.cache`), which is not served by `res.sendFile` (and maybe `express.static`?) by default. Changing https://github.com/actualbudget/actual/blob/23f1bae7db84b111e6c3a69520d3a74e2d529011/packages/sync-server/src/app.ts#L146-L149 to ```ts app.use(express.static(config.get('webRoot'), { index: false, dotfiles:'allow' })); app.get('/{*splat}', (req, res) => res.sendFile(config.get('webRoot') + '/index.html', {dotfiles: 'allow'})); ``` makes the server work as expected.
Author
Owner

@gediminasel commented on GitHub (Aug 28, 2025):

I'm not 100% sure if dottfiles:'allow' is necessary on express.static rule, website seems to work fine without it. Assets like http://localhost:5006/maskable-512x512.png load fine too.

And adding {dotfiles: 'allow' to res.sendFile seems like a safe change: it always serves the same index.html file, WDYT?

@gediminasel commented on GitHub (Aug 28, 2025): I'm not 100% sure if `dottfiles:'allow'` is necessary on `express.static` rule, website seems to work fine without it. Assets like http://localhost:5006/maskable-512x512.png load fine too. And adding `{dotfiles: 'allow'` to `res.sendFile` seems like a safe change: it always serves the same `index.html` file, WDYT?
Author
Owner

@gediminasel commented on GitHub (Aug 28, 2025):

I quickly looked at express code and this function: 6fc83dc463/index.js (L403)

It seems like express.static doesn't need dotfiles: 'allow' because it send only checks if path doesn't contain dotfiles, which in case of express.static is the path from url and the root is passed via opts.root.

In contrast, sendFile is called, webRoot is concatenated with index.html and passed via path variable.

I tested and this seems to work as an alternative (and likely more expressive) fix:

    app.use(express.static(config.get('webRoot'), { index: false }));
    app.get('/{*splat}', (req, res) => res.sendFile('index.html', {root: config.get('webRoot')}));
@gediminasel commented on GitHub (Aug 28, 2025): I quickly looked at express code and this function: https://github.com/pillarjs/send/blob/6fc83dc4631abecc9b4fb05b0ee2c90400751b43/index.js#L403 It seems like `express.static` doesn't need `dotfiles: 'allow'` because it `send` only checks if `path` doesn't contain dotfiles, which in case of `express.static` is the path from url and the root is passed via `opts.root`. In contrast, `sendFile` is called, `webRoot` is concatenated with `index.html` and passed via `path` variable. I tested and this seems to work as an alternative (and likely more expressive) fix: ```ts app.use(express.static(config.get('webRoot'), { index: false })); app.get('/{*splat}', (req, res) => res.sendFile('index.html', {root: config.get('webRoot')})); ```
Author
Owner

@culpeppers commented on GitHub (Aug 29, 2025):

I just want to add that this issue also occurs when using Actual as a web app on iOS.

@culpeppers commented on GitHub (Aug 29, 2025): I just want to add that this issue also occurs when using Actual as a web app on iOS.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#2427