Tencent/matrix · error · FileNotFoundException

fialed to create new hprof file since path: $absolutePath…

Error message

fialed to create new hprof file since path: $absolutePath is not writable

What it means

HprofFileManager's File.reserve() throws FileNotFoundException when the hprof output directory neither exists nor can be created/made writable (mkdirs() fails or canWrite() is false). It logs the message and throws so callers fail fast instead of writing hprof dumps to an unusable location.

Solutions

  1. Use an app-private directory like context.cacheDir or context.filesDir for hprof output.
  2. Check available storage and mount state (Environment.getExternalStorageState) before dumping.
  3. Request/verify write permissions (legacy WRITE_EXTERNAL_STORAGE if using shared storage).
  4. Catch FileNotFoundException from the dumper and fall back to an alternate directory.

Example fix

// before
val hprofDir = File(Environment.getExternalStorageDirectory(), "hprof") // may be unwritable
// after
val hprofDir = File(context.cacheDir, "hprof").apply { mkdirs() }
HprofFileManager(context, hprofDir, maxSpace)
Defensive patterns

Strategy: fallback

Validate before calling

fun usableHprofDir(context: Context, preferred: File): File {
  return if (preferred.exists() || preferred.mkdirs()) {
    if (preferred.canWrite()) preferred else File(context.cacheDir, "hprof").apply { mkdirs() }
  } else File(context.cacheDir, "hprof").apply { mkdirs() }
}

Type guard

fun File.isWritableDir(): Boolean = isDirectory && canWrite()

Try / catch

try {
  hprofFileManager.prepare()
} catch (e: FileNotFoundException) {
  MatrixLog.e(TAG, "hprof dir unusable, falling back to cacheDir")
  hprofFileManager = HprofFileManager(context, File(context.cacheDir, "hprof"), maxSpace)
  hprofFileManager.prepare()
}

Prevention

When it happens

Trigger: Preparing the hprof directory (via prepare -> reserve) at a path where mkdirs() fails (read-only filesystem, missing parent permissions, storage unmounted) or where the created directory is not writable.

Common situations: App targeting scoped storage paths it cannot write; external storage unmounted/full; configured hprof dir under a path not created due to SELinux/permission restrictions on certain OEM ROMs.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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

Appendix: source

Thrown at matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-android/src/main/java/com/tencent/matrix/resource/dumper/HprofFileManager.kt:66

    fun prepareHprofFile(prefix: String = "", deleteSoon: Boolean = false): File {
        hprofStorageDir.prepare(deleteSoon)
        return File(hprofStorageDir, getHprofFileName(prefix))
    }

    fun clearAll() {
        hprofStorageDir.deleteRecursively()
    }

    private fun File.prepare(deleteSoon: Boolean) {
        reserve()
        makeSureEnoughSpace(deleteSoon)
    }

    private fun File.reserve() {
        if (!exists() && (!mkdirs() || !canWrite())) {
            "fialed to create new hprof file since path: $absolutePath is not writable".let {
                MatrixLog.e(TAG, it)
                throw FileNotFoundException(it)
            }
        }
    }

    private fun File.makeSureEnoughSpace(deleteSoon: Boolean) {
        if (!isDirectory) {
            return
        }
        lru()
        if (freeSpace < CLEAN_THRESHOLD) {
            listFiles()?.forEach { it.delete() }
        }
        if (freeSpace < if (deleteSoon) MIN_FREE_SPACE else CLEAN_THRESHOLD) {
            throw FileNotFoundException("free space($freeSpace) less than $CLEAN_THRESHOLD, skip dump hprof")
        }
    }

    private fun File.lru() {

View on GitHub (pinned to 3b8293bd65)