Tencent/matrix · error · TaskInitException

TAG + "---The path of tool 'nm' is not given!"

Error message

TAG + "---The path of tool 'nm' is not given!"

What it means

UnStrippedSoCheckTask.init() throws TaskInitException when the required external 'nm' (GNU nm symbol-listing) tool path parameter is missing or empty. This task shells out to nm to detect unstripped .so files, so it cannot start without it. Thrown before any APK analysis begins.

Solutions

  1. Pass the nm binary path via the task params, e.g. params.put(JobConstants.PARAM_TOOL_NM, "/usr/bin/nm") or the NDK toolchain nm (NDK .../toolchains/llvm/prebuilt/<host>/bin/llvm-nm).
  2. Install binutils/NDK if nm is not present and set the resulting absolute path.
  3. Verify via `which nm` that the path exists and is executable before launching the job.
  4. If using $ENV_VAR style in the configured path, ensure the env var is exported in the environment running matrix (the task resolves $(VAR) patterns via System.getenv).

Example fix

// before
Map<String, String> params = new HashMap<>();
// after
params.put(JobConstants.PARAM_TOOL_NM, "/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-nm");
Defensive patterns

Strategy: validation

Validate before calling

String nm = params.get(JobConstants.PARAM_TOOL_NM);
if (nm == null || nm.trim().isEmpty()) {
    throw new IllegalArgumentException("PARAM_TOOL_NM must be set to an absolute nm/llvm-nm path");
}
if (!new File(nm).canExecute()) throw new IllegalArgumentException("nm not executable: " + nm);

Try / catch

try {
    job.run();
} catch (TaskInitException e) {
    if (e.getMessage().contains("tool 'nm' is not given")) {
        configureNmToolPath();
    } else throw e;
}

Prevention

When it happens

Trigger: Calling the apk-canary job with PARAM_TOOL_NM unset, empty, or null in the task params map.

Common situations: Running the so-stripping check in a fresh CI environment where the Android NDK path was never configured; migrating matrix config and dropping the tool parameter; forgetting that the nm tool path must be provided (Linux/macOS).

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

public class UnStrippedSoCheckTask extends ApkTask {

    private static final String TAG = "Matrix.UnStrippedSoCheckTask";

    private File libDir;
    private String toolnmPath;

    public UnStrippedSoCheckTask(JobConfig jobConfig, Map<String, String> params) {
        super(jobConfig, params);
        type = TASK_TYPE_UNSTRIPPED_SO;
    }

    @Override
    public void init() throws TaskInitException {
        super.init();
        final String inputPath = config.getUnzipPath();
        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)) {

View on GitHub (pinned to 3b8293bd65)