Tencent/matrix · error · TaskInitException

TAG + "---APK-UNZIP-PATH can not be null!"

Error message

TAG + "---APK-UNZIP-PATH can not be null!"

What it means

UnusedAssetsTask.init() throws TaskInitException when the unzipped APK directory (config.getUnzipPath(), APK-UNZIP-PATH) is null or empty. The task walks the assets/ directory of the unzipped APK to detect unused assets.

Solutions

  1. Set the unzip path in MatrixConfig (or CLI flag) to the unzipped APK root.
  2. Make sure the unzip task runs before UnusedAssetsTask in the pipeline.
  3. Confirm the directory contains an assets/ subdirectory to scan.

Example fix

// before
MatrixConfig cfg = new MatrixConfig.Builder().build();
// after
MatrixConfig cfg = new MatrixConfig.Builder().setApkPath(apk).setApkUnzipPath(unzipDir).build();
Defensive patterns

Strategy: validation

Validate before calling

String unzipPath = config.getApkUnzipPath();
if (unzipPath == null || unzipPath.isEmpty() || !new File(unzipPath).isDirectory()) {
    throw new IllegalStateException("APK-UNZIP-PATH must point to an existing unzipped-APK directory");
}

Try / catch

try {
    job.run();
} catch (TaskInitException e) {
    if (e.getMessage().contains("APK-UNZIP-PATH can not be null")) {
        runUnzipTaskThenRetry();
    } else throw e;
}

Prevention

When it happens

Trigger: Running the unused-assets check without an unzip step, or with the unzip-path config key missing/null in MatrixConfig.

Common situations: Running only this task manually without preparing inputs; a CI refactor stopped passing the unzip directory between pipeline stages; typo in config key.

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/a45cf5818bdf3923. Report an issue: GitHub.

Appendix: source

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

    private final Set<String> assetsPathSet;
    private final Set<String> assetRefSet;

    public UnusedAssetsTask(JobConfig config, Map<String, String> params) {
        super(config, params);
        type = TaskFactory.TASK_TYPE_UNUSED_ASSETS;
        dexFileNameList = new ArrayList<>();
        ignoreSet = new HashSet<>();
        assetsPathSet = new HashSet<>();
        assetRefSet = new HashSet<>();
    }

    @Override
    public void init() throws TaskInitException {
        super.init();

        String inputPath = config.getUnzipPath();
        if (Util.isNullOrNil(inputPath)) {
            throw new TaskInitException(TAG + "---APK-UNZIP-PATH can not be null!");
        }
        inputFile = new File(inputPath);
        if (!inputFile.exists()) {
            throw new TaskInitException(TAG + "---APK-UNZIP-PATH '" + inputPath + "' is not exist!");
        } else if (!inputFile.isDirectory()) {
            throw new TaskInitException(TAG + "---APK-UNZIP-PATH '" + inputPath + "' is not directory!");
        }
        if (params.containsKey(JobConstants.PARAM_IGNORE_ASSETS_LIST) && !Util.isNullOrNil(params.get(JobConstants.PARAM_IGNORE_ASSETS_LIST))) {
            String[] ignoreAssets = params.get(JobConstants.PARAM_IGNORE_ASSETS_LIST).split(",");
            Log.i(TAG, "ignore assets %d", ignoreAssets.length);
            for (String ignore : ignoreAssets) {
                ignoreSet.add(Util.globToRegexp(ignore));
            }
        }

        File[] files = inputFile.listFiles();
        if (files != null) {
            for (File file : files) {

View on GitHub (pinned to 3b8293bd65)