Tencent/matrix · error · TaskInitException

---Can not find the tool 'nm'!

Error message

---Can not find the tool 'nm'!

What it means

After resolving (including env-var interpolation of paths like $VAR), MultiSTLCheckTask.init() checks FileUtil.isLegalFile(toolnmPath). If the nm tool path does not point to an existing legal file, it throws TaskInitException with this message.

Solutions

  1. Verify the nm path exists: ls the exact configured path; fix it to the real binary location.
  2. Install the Android NDK / command-line tools containing nm (llvm-nm).
  3. Check that environment variables referenced in the path (e.g. $ANDROID_NDK_HOME) are exported in the process environment.

Example fix

// before
params.put(JobConstants.PARAM_TOOL_NM, "$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/nm"); // removed in new NDK
// after
params.put(JobConstants.PARAM_TOOL_NM, System.getenv("ANDROID_NDK_HOME") + "/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-nm");
Defensive patterns

Strategy: validation

Validate before calling

String nm = params.get(JobConstants.PARAM_TOOL_NM);
File nmFile = new File(nm);
if (!nmFile.isFile() || !nmFile.canExecute()) {
    throw new IllegalStateException("nm tool not found or not executable: " + nm);
}

Try / catch

try {
    task.init();
} catch (TaskInitException e) {
    if (e.getMessage().contains("Can not find the tool 'nm'")) {
        // fix path: verify NDK installation and env-var interpolation
    }
}

Prevention

When it happens

Trigger: PARAM_TOOL_NM is set but the path does not exist or is not a regular file: wrong NDK version path, nm binary not installed, or an embedded $ENV_VAR failed to resolve (env var unset) leaving a bogus path.

Common situations: CI image without the Android NDK installed; $ANDROID_NDK or similar env var missing so interpolation yields an invalid path; macOS vs Linux toolchain path mix-ups; NDK upgrade changed tool layout (prebuilt/<abi>/ vs llvm-nm).

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/f35d1bab9ed6b47a. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-apk-canary/src/main/java/com/tencent/matrix/apk/model/task/MultiSTLCheckTask.java:83

        toolnmPath = params.get(JobConstants.PARAM_TOOL_NM);
        if (Util.isNullOrNil(toolnmPath)) {
            throw new TaskInitException(TAG + "---The path of tool 'nm' is not given!");
        } else {
            Pattern envPattern = Pattern.compile("(\\$[a-zA-Z_-]+)");
            Matcher matcher =  envPattern.matcher(toolnmPath);
            while (matcher.find()) {
                if (!Util.isNullOrNil(matcher.group())) {
                    String env = System.getenv(matcher.group().substring(1));
                    Log.d(TAG, "%s -> %s", matcher.group().substring(1), env);
                    if (!Util.isNullOrNil(env)) {
                        toolnmPath = toolnmPath.replace(matcher.group(), env);
                    }
                }
            }
            Log.i(TAG, "toolnm pah is %s", toolnmPath);
        }
        if (!FileUtil.isLegalFile(toolnmPath)) {
            throw new TaskInitException(TAG + "---Can not find the tool 'nm'!");
        }
        if (!Util.isNullOrNil(inputPath)) {
            Log.i(TAG, "inputPath:%s", inputPath);
            libDir = new File(inputPath, "lib");
        } else {
            throw new TaskInitException(TAG + "---APK-UNZIP-PATH can not be null!");
        }

    }

    private boolean isStlLinked(File libFile) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder(toolnmPath, "-D", "-C", libFile.getAbsolutePath());
        Process process = processBuilder.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        while (line != null) {
            String[] columns = line.split(" ");
            Log.d(TAG, "%s", line);

View on GitHub (pinned to 3b8293bd65)