Skip to content

SEA: access() on exisiting folder path in snapshot throws error #260

@julianpoemp

Description

@julianpoemp

What version of pkg are you using?

pkg 6.17.0 from fix/sea-macos-signing branch

What version of Node.js are you using?

v22.18.0

What operating system are you using?

macOS

What CPU architecture are you using?

arm64

What Node versions, OSs and CPU architectures are you building for?

node22-macos-arm64

Describe the Bug

I'm facing a strange bug on a SEA executable: I try to check if a folder exists in the snapshot using fs.access(): If the path ends with a separator (on Unix "/") access incorrectly throws an error, that the path did not exist. If I remove the separator at the end, it works. That may be no big problem if you are able to change the path. But if a module adds the separator by itself (like nestjs-i18n) you are not able to change it.

Compare the last lines of each of the following outputs.

Output with PKG without SEA:

./dist/pkg/server-macos-arm64 
[Nest] 8797  - 04/22/2026, 3:35:02 PM     LOG [NestFactory] Starting Nest application...
[Nest] 8797  - 04/22/2026, 3:35:02 PM     LOG [InstanceLoader] AppModule dependencies initialized +4ms
[Nest] 8797  - 04/22/2026, 3:35:02 PM     LOG [RoutesResolver] AppController {/api}: +0ms
[Nest] 8797  - 04/22/2026, 3:35:02 PM     LOG [RouterExplorer] Mapped {/api, GET} route +0ms
[Nest] 8797  - 04/22/2026, 3:35:02 PM     LOG [NestApplication] Nest application successfully started +1ms
[Nest] 8797  - 04/22/2026, 3:35:02 PM     LOG 🚀 Application is running on: http://localhost:3000/api
TEST if Directory exists
/snapshot/yao-pkg-nestjs-sea-example/apps/server/dist: true
/snapshot/yao-pkg-nestjs-sea-example/apps/server/dist/: true

Output with PKG and SEA Enhanced:

./dist/sea-enhanced/server-macos-arm64
(node:8326) ExperimentalWarning: SQLite is an experimental feature and might change at any time
(Use `server-macos-arm64 --trace-warnings ...` to show where the warning was created)
[Nest] 8326  - 04/22/2026, 3:31:57 PM     LOG [NestFactory] Starting Nest application...
[Nest] 8326  - 04/22/2026, 3:31:57 PM     LOG [InstanceLoader] AppModule dependencies initialized +5ms
[Nest] 8326  - 04/22/2026, 3:31:57 PM     LOG [RoutesResolver] AppController {/api}: +1ms
[Nest] 8326  - 04/22/2026, 3:31:57 PM     LOG [RouterExplorer] Mapped {/api, GET} route +1ms
[Nest] 8326  - 04/22/2026, 3:31:57 PM     LOG [NestApplication] Nest application successfully started +1ms
[Nest] 8326  - 04/22/2026, 3:31:57 PM     LOG 🚀 Application is running on: http://localhost:3000/api
TEST if Directory exists
/snapshot/yao-pkg-nestjs-sea-example/apps/server/dist: true
ERROR: Error: ENOENT: no such file or directory, access '/snapshot/yao-pkg-nestjs-sea-example/apps/server/dist/'
/snapshot/yao-pkg-nestjs-sea-example/apps/server/dist/: false

Code

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { access } from 'node:fs/promises';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const globalPrefix = 'api';
  app.setGlobalPrefix(globalPrefix);
  const port = process.env.PORT || 3000;
  await app.listen(port);
  Logger.log(
    `🚀 Application is running on: http://localhost:${port}/${globalPrefix}`,
  );

  console.log(`\nTEST if Directory exists`);
  console.log(`${__dirname}: ${await pathExists(__dirname)}`);
  console.log(`${__dirname + '/'}: ${await pathExists(__dirname + '/')}`);
}

async function pathExists(path: string) {
  try {
    await access(path);
    return true;
  } catch (e) {
    console.log(`ERROR: ${e}`);
    return false;
  }
}

bootstrap();

Expected Behavior

access() on a path in the snapshot of a SEA binary should succeed nevertheless the path ends with "/" or not.

To Reproduce

I was able to reproduce it. You find an example on the no-access-snapshot branch here: yao-pkg-nestjs-sea-example/no-access-snapshot

Without SEA

npm run package && ./dist/pkg/server-macos-arm64
-> shows correct output

Without SEA Enhanced

npm run package:sea:enhanced && ./dist/sea-enahnced/server-macos-arm64
-> shows incorrect output

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions