alibaba/ARouter · error · IOException

Cannot replace temporary ARouter transform output: <temporar

Error message

Cannot replace temporary ARouter transform output: <temporary>

What it means

Thrown by ScopedClassTransformer when a stale temporary output file (output.name + '.tmp') exists from a previous run and File.delete() fails to remove it. The transform writes to a .tmp file first and renames it, so an undeletable temp file blocks the build with this IOException.

Source

Thrown at arouter-gradle-plugin/src/main/groovy/com/alibaba/android/arouter/register/core/ScopedClassTransformer.groovy:45

    static Result transform(Collection<File> jars, Collection<File> directories, File output) {
        Map<String, Set<String>> implementations = new LinkedHashMap<>()
        REGISTER_INTERFACES.each { implementations.put(it, new TreeSet<String>()) }

        jars.each { scanJar(it, implementations) }
        directories.each { scanDirectory(it, implementations) }

        Set<String> registrations = new TreeSet<>()
        implementations.values().each { registrations.addAll(it) }

        File parent = output.parentFile
        if (!parent.isDirectory() && !parent.mkdirs()) {
            throw new IOException('Cannot create ARouter transform output directory: ' + parent)
        }

        File temporary = new File(parent, output.name + '.tmp')
        if (temporary.exists() && !temporary.delete()) {
            throw new IOException('Cannot replace temporary ARouter transform output: ' + temporary)
        }

        boolean logisticsCenterFound = false
        Set<String> writtenEntries = new HashSet<>()

        try {
            JarOutputStream jarOutput = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(temporary)))
            try {
                jars.each { File jar ->
                    logisticsCenterFound |= copyJar(jar, jarOutput, writtenEntries, registrations)
                }
                directories.each { File directory ->
                    logisticsCenterFound |= copyDirectory(directory, jarOutput, writtenEntries, registrations)
                }
            } finally {
                jarOutput.close()
            }

View on GitHub (pinned to 84f451d244)

Solutions

  1. Manually delete the reported <output>.tmp file and rebuild.
  2. Run `./gradlew clean` to wipe stale build outputs.
  3. Ensure no other Gradle daemon/IDE build is running concurrently and that the build dir is writable/owned by the current user.
Defensive patterns

Strategy: try-catch

Validate before calling

File temporary = new File(output.parentFile, output.name + '.tmp')
if (temporary.exists() && !temporary.canWrite()) {
    throw new IllegalStateException("Stale temp file not deletable: " + temporary)
}

Try / catch

try {
    transform(...)
} catch (IOException e) {
    if (e.message?.contains('Cannot replace temporary ARouter transform output')) {
        assert new File(e.message.split(': ').last()).delete()
        // retry the transform once
    } else throw e
}

Prevention

When it happens

Trigger: A leftover <output>.tmp file from an interrupted build exists in the output directory and cannot be deleted — file locked by another process/AV scanner, owned by another user, or a read-only filesystem.

Common situations: Killing Gradle mid-transform leaving orphaned .tmp files; Windows file locking by antivirus/IDE indexing; parallel builds racing over the same output directory; CI caches restored with wrong ownership.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of alibaba/ARouter@84f451d244 (2026-09-06). Data as JSON: /api/errors/76fb1adbaf627bb9. Report an issue: GitHub.