Skip to content

Troubleshooting

s edited this page Aug 4, 2026 · 7 revisions

Troubleshooting

Start with the first specific failure. Later errors are often consequences of the first one.

For exact command options in the installed version:

supernote-module --help
supernote-module help <command>

The command is not found

Confirm Python and pip:

python3 --version
python3 -m pip --version

On Windows:

py --version
py -m pip --version

Install or upgrade:

python3 -m pip install --upgrade supernote-module-generator

Then check:

supernote-module --version

If pip reports a successful installation but the executable is still unavailable, the Python scripts directory is probably not on PATH. Run the package through the same Python environment or add that scripts directory to PATH.

Also confirm that the terminal was reopened after changing environment variables.

The current directory is not a Supernote plugin

The command must run from a directory containing:

PluginConfig.json
package.json
android/
android/settings.gradle

android/settings.gradle.kts is also accepted.

The generator does not search parent directories. Move to the plugin root and rerun the command.

Doctor cannot find the Android SDK

Doctor reads:

ANDROID_HOME
ANDROID_SDK_ROOT

and requires the selected SDK to contain:

platforms/android-35/android.jar

An Android Studio build can work while a separate terminal lacks the same environment variable.

Check the current value:

Linux or macOS:

printf '%s\n' "$ANDROID_HOME"
printf '%s\n' "$ANDROID_SDK_ROOT"

PowerShell:

$env:ANDROID_HOME
$env:ANDROID_SDK_ROOT

Set one variable to the actual SDK directory.

Common defaults are:

Linux:   ~/Android/Sdk
macOS:   ~/Library/Android/sdk
Windows: %LOCALAPPDATA%\Android\Sdk

These are examples, not guaranteed paths.

After setting it, rerun:

supernote-module doctor --type native

Do not install another SDK until you have confirmed that the existing SDK is merely undiscoverable.

Doctor reports the wrong Java version

Java 17 or newer is required.

Check:

java --version

If multiple JDKs are installed, ensure that the terminal's PATH and JAVA_HOME refer to the intended JDK before rerunning Doctor.

Doctor reports a package-manager conflict

If both of these exist:

package-lock.json
yarn.lock

the generator refuses to guess which package manager owns the plugin.

Choose explicitly:

supernote-module add local-math --type native --package-manager npm --yes

or:

supernote-module add local-math --type native --package-manager yarn --yes

Before choosing, determine which lockfile the plugin actually uses. Do not refresh both lockfiles.

Doctor reports a CMake or NDK failure

JNI and JSI require:

  • CMake 3.22.1 or newer.
  • An Android NDK with Clang capable of compiling C23 and C++23.
  • The arm64-v8a Android target used by generated modules.

Run the narrow check:

supernote-module doctor --type jni

or:

supernote-module doctor --type jsi

Doctor searches ANDROID_NDK_HOME, ANDROID_NDK_ROOT, and NDK installations under the selected Android SDK.

Read the first failed Native check before changing Gradle or generated CMake files.

Add changed package.json even with --skip-install

This is expected.

--skip-install skips the npm or Yarn command and lockfile refresh. Add still:

  • Creates the generated package.
  • Adds the local dependency to package.json.
  • Adds required parent integration.

Run the package manager later:

npm install

or:

yarn install

The module cannot be imported

Check the dependency declaration:

node -p "require('./package.json').dependencies['local-math']"

It should resemble:

file:./local_modules/local-math

Check the installed dependency link:

node -p "require.resolve('local-math/package.json')"

If Add used --skip-install, run the plugin's package manager.

Then validate:

supernote-module validate local-math

Validate reports an integration or dependency-link failure

Structural validation distinguishes between:

  • Missing or invalid generated files.
  • Missing parent dependency.
  • Missing Gradle integration.
  • Missing installed local dependency link.
  • Export or declaration problems.

Correct the problem named by the first issue.

Do not run Update automatically for every validation failure. In particular, an intentionally skipped dependency installation normally requires npm install or yarn install, not Update.

An exported function does not appear

For a Native Module, check:

  • The method imports this module's generated SupernoteExport.
  • The class and method are public.
  • The class is concrete.
  • Its constructor is supported.
  • Every parameter and return type is supported.
  • The export name is unique.

For JNI or JSI, check:

  • // @SupernoteExport is immediately before the function definition.
  • The file ends in .cc, .cpp, or .cxx.
  • The function is a top-level definition.
  • It is not overloaded.
  • Every parameter is named.
  • Parameters and return values use supported by-value types.
  • The export name is unique.

Then run:

supernote-module validate <package-name> --build --verbose

The Android build fails

Use the concise error first, then rerun with full subprocess output:

supernote-module validate <package-name> --build --verbose

Find the first compiler, KSP, Gradle, CMake, linker, or dependency error. Errors after that point may be cascading failures.

Use --debug only when the tool itself reports an internal error or asks for a traceback.

The generated declaration is stale

Run:

supernote-module validate <package-name> --build

The build step scans exported functions and regenerates the bridge and TypeScript declaration.

If it remains stale, inspect the export rules for the selected module type and confirm that the build actually completed.

Update removed a custom change

Update owns generated package, bridge, registration, Gradle, CMake, loader, and declaration files.

Restore the customization from version control or a patch. Document it and expect to reapply it after later Updates.

Move implementation code into the preserved implementation root whenever possible.

JSI compiles but does not load

A successful build proves only that the code can be compiled.

Check device logs for:

  • Native library loading errors.
  • Missing shared-library dependencies.
  • Linker namespace restrictions.
  • Permission denied.
  • SELinux { execute } denials.
  • PluginHost or React Native runtime incompatibility.

Test the exact firmware and PluginHost configuration you intend to support. Success on a permissive or userdebug environment does not prove support on an enforcing retail environment.

A permission or SELinux denial occurs before the exported C++ function runs. Rewriting the function will not fix that environment restriction.

The plugin freezes after a JSI call

The function is running synchronously on the JavaScript thread.

JSI can perform file access, network access, waits, and long computations, but JavaScript remains blocked until the call returns.

If that blocking is not acceptable, reduce the work, reduce the input, cache the result, or move the operation behind a Native JNI Module with a Promise-based interface.

An operation was interrupted

Run the generator again before deleting recovery files:

supernote-module

The startup recovery process attempts to roll back or reconcile the previous transaction.

If the command exits with code 3, follow the displayed recovery command. Do not continue editing the affected generated files until the partial operation has been understood.

Report an internal error

Rerun with:

supernote-module <command> --debug

Include:

  • The generator version.
  • The command.
  • The first visible error.
  • The debug traceback.
  • The operating system and shell.
  • Whether the plugin uses npm or Yarn.
  • The module type.
  • Whether the working tree had pre-existing changes.

Remove private paths, credentials, or proprietary source before sharing logs publicly.

Clone this wiki locally