HakobuHakobu

Troubleshooting

Common issues and solutions when using Hakobu.

This page covers debugging tools, common errors, and solutions for issues you may encounter when packaging or running Hakobu executables.

Debug Flags

Build-time debugging

Use --debug (or -d) when packaging to get detailed diagnostics about what Hakobu is doing:

hakobu . --debug --output ./dist/app

This prints verbose information about file resolution, dependency tracing, target selection, and binary production.

Runtime debugging

After packaging with --debug, you can inspect the snapshot contents at runtime using the DEBUG_PKG environment variable:

# Level 1: Print the snapshot tree and symlink table
DEBUG_PKG=1 ./dist/app

# Level 2: Also mock fs to log every filesystem method call
DEBUG_PKG=2 ./dist/app

On Windows:

set DEBUG_PKG=1
dist\app.exe

Runtime debugging requires the executable to have been built with --debug. Without it, the diagnostic prelude is not included and DEBUG_PKG has no effect.

Size analysis

Use the SIZE_LIMIT_PKG and FOLDER_LIMIT_PKG environment variables to identify large files and folders in the snapshot:

# Print files larger than 2 MB and folders larger than 5 MB
SIZE_LIMIT_PKG=2097152 FOLDER_LIMIT_PKG=5242880 DEBUG_PKG=1 ./dist/app

Defaults when not set:

  • SIZE_LIMIT_PKG: 5 MB (5,242,880 bytes)
  • FOLDER_LIMIT_PKG: 10 MB (10,485,760 bytes)

Environment Variables

Build-time

VariablePurpose
HAKOBU_CACHE_PATHOverride the base binary cache directory (default: ~/.hakobu/cache/)
HAKOBU_OFFLINESet to 1 to prevent any network access during packaging

Runtime

VariablePurpose
DEBUG_PKGSet to 1 or 2 to enable runtime snapshot diagnostics
SIZE_LIMIT_PKGFile size threshold (bytes) for snapshot size warnings
FOLDER_LIMIT_PKGFolder size threshold (bytes) for snapshot size warnings
HAKOBU_ADDON_CACHEOverride the native addon extraction cache directory
PKG_NATIVE_CACHE_PATHLegacy equivalent of HAKOBU_ADDON_CACHE
HAKOBU_EXTERNAL_{NAME}Override the path to a declared external artifact
CHDIROverride process.chdir behavior at startup
PKG_STRICT_VEREnable assertions that each appended file is real (not a symlink)

Common Errors

Base binary not found

Error! Base binary not found for node24-linux-x64

Cause: The prebuilt base binary could not be downloaded or is missing from the cache.

Solutions:

  • Check your network connection. Hakobu downloads base binaries on first use.
  • If behind a proxy, configure HTTP_PROXY / HTTPS_PROXY environment variables.
  • Use hakobu targets to see which binaries are cached and which are available.
  • Use --build / -b to build the base binary locally instead of downloading.
  • For air-gapped environments, pre-populate the cache on a networked machine and copy ~/.hakobu/cache/ to the target machine. Then set HAKOBU_OFFLINE=1.

Native addon failures

HAKOBU_ADDON_NOT_FOUND: Loading native addon from snapshot: /snapshot/myapp/node_modules/sharp/build/Release/sharp.node

Cause: A .node native addon file was not found in the snapshot or could not be extracted at runtime.

Solutions:

  • Ensure the native addon is compiled for the target platform before packaging. Cross-compilation is not handled by Hakobu.
  • Check that the addon's .node file exists in node_modules at build time.
  • Verify the extraction cache is writable. Override with HAKOBU_ADDON_CACHE=/path/to/cache.
HAKOBU_ADDON_PLATFORM_MISMATCH: ...

Cause: The native addon was compiled for a different platform than the target.

Solution: Rebuild the addon for the correct platform/architecture before packaging.

HAKOBU_ADDON_EXTRACT_FAILED: Extracting addon to: /home/user/.hakobu/addons/...

Cause: Hakobu could not extract the addon to the cache directory.

Solutions:

  • Check filesystem permissions for ~/.hakobu/addons/.
  • Override the cache location with HAKOBU_ADDON_CACHE=/writable/path.
  • Ensure there is enough disk space.

ESM resolution issues

Symptom: ERR_MODULE_NOT_FOUND or ERR_UNSUPPORTED_DIR_IMPORT at runtime.

Solutions:

  • Ensure your package.json has "type": "module" if your entry point uses import syntax.
  • Use file extensions in import specifiers. Node 24 ESM requires explicit extensions (e.g. import './utils.js', not import './utils').
  • Check that package.json "exports" map is correctly configured for any packages that use it.
  • Dynamic import() only supports static string paths inside Hakobu snapshots. Computed import paths will not resolve.

If you see import.meta.url returning a file:///snapshot/... URL, this is expected behavior. Hakobu maps the snapshot filesystem under the /snapshot/ prefix.

External artifact not found

HAKOBU_EXTERNAL_NOT_FOUND: Locating required external artifact: camoufox-browser

Cause: A declared external artifact could not be found at any search location.

Solutions:

  • Set the environment variable HAKOBU_EXTERNAL_{NAME} to the artifact path (uppercase, dashes replaced with underscores).
  • Place the artifact at {executableDir}/externals/{name}/.
  • Verify the artifact is declared in your package.json:
package.json
{
  "hakobu": {
    "externals": ["camoufox-browser"]
  }
}
HAKOBU_EXTERNAL_NOT_DECLARED: Looking up external artifact: my-tool

Cause: Trying to resolve an external that was not declared in the Hakobu config.

Solution: Add the external to the "externals" array in your package.json "hakobu" config.

Output file conflicts

Error! Refusing to overwrite input file

Cause: The resolved output path is the same as the input file.

Solution: Specify an explicit --output path that differs from the entry point.

Error! Refusing to overwrite non-file output

Cause: The output path points to an existing directory.

Solution: Specify a file path for single-target builds, or use a directory path with multi-target builds.

Compression errors

Error! Invalid compression algorithm zstd (should be None, Brotli or Gzip)

Solution: Use one of the supported compression algorithms: None, Brotli (or br), or GZip (or gz).

Large Binary Size

If your packaged executable is unexpectedly large:

  1. Inspect the snapshot using runtime diagnostics:
SIZE_LIMIT_PKG=1048576 DEBUG_PKG=1 ./dist/app 2>&1 | head -100

This will print files larger than 1 MB, helping you identify unexpected inclusions.

  1. Check for unnecessary dependencies being pulled in. Hakobu traces from the entry point, but transitive dependencies can bring in large files.

  2. Use the assets field to explicitly control which non-code files are included, rather than relying on automatic inclusion.

  3. Use compression to reduce the executable size:

hakobu . --compress Brotli --output ./dist/app
  1. Use hakobu inspect to analyze your project without producing an executable:
hakobu inspect ./my-app

Known Runtime Limitations

LimitationWorkaround
process.execPath -e "code" does not workUse script files instead of -e for child eval
linuxstatic-arm64 target is blockedUse linux-arm64 instead (requires glibc on target)
Bytecode + bundle cannot be combinedUse one or the other
Dynamic import() with computed pathsUse static string paths or restructure imports
Node 24 onlyNo support for older Node versions

If you encounter an issue not covered here, check the GitHub issues or run hakobu doctor ./my-app to get a diagnostic report of your project's packaging readiness.

On this page