Tencent/matrix · error · RuntimeException
Input file( ) should not be same with output!
Error message
Input file(${classFile.getCanonicalPath()}) should not be same with output! What it means
Thrown by MethodTracer.innerTraceMethodFromSrc when the computed output file path is canonically identical to the input class file, which would mean overwriting the input in place — an invariant the tracer forbids. The output path is derived by string-replacing the input dir with the output dir, so identical canonical paths indicate the transform mapped the file onto itself.
Solutions
- Ensure the output directory passed to the transform differs from the input directory
- Avoid symlinked directories (or use real canonical paths) when configuring input/output dirs
- Check incremental build state: clean the module (gradle clean) to reset stale transform directories
- Verify the plugin's directory provider maps input to a distinct output location per AGP Transform API contract
Example fix
// before File output = input // same dir // after File output = new File(input.getParentFile(), input.getName() + '-traced') assert output.canonicalPath != input.canonicalPath
Defensive patterns
Strategy: validation
Validate before calling
if (inputDir.canonicalPath == outputDir.canonicalPath) {
throw new IllegalArgumentException('transform input and output directories must differ')
} Try / catch
try {
methodTracer.trace(srcMap, jarList, classLoader, false)
} catch (RuntimeException e) {
if (e.message?.contains('should not be same with output')) {
logger.error('Input/output directory collision: use distinct transform output directories, avoid symlinks', e)
}
throw e
} Prevention
- Always provide a distinct output directory from the transform API (getSecondaryFiles/output mapping)
- Avoid symlinked build paths that make different paths canonically equal
- Run gradle clean when switching transform configurations to clear stale incremental state
When it happens
Trigger: Calling the trace transform with input directory equal to the output directory (or output nested/symlinked so canonical paths coincide), so changedFileOutput resolves to the same file as the input class.
Common situations: Misconfigured incremental transform directories where the plugin passes the same folder for input and output; symlinked build directories (e.g. macOS /tmp symlink to /private/tmp) making distinct paths canonically equal.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/a57e67b5a85a62c2.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-gradle-plugin/src/main/java/com/tencent/matrix/trace/MethodTracer.java:139
private void innerTraceMethodFromSrc(File input, File output, ClassLoader classLoader, boolean ignoreCheckClass) {
ArrayList<File> classFileList = new ArrayList<>();
if (input.isDirectory()) {
listClassFiles(classFileList, input);
} else {
classFileList.add(input);
}
for (File classFile : classFileList) {
InputStream is = null;
FileOutputStream os = null;
try {
final String changedFileInputFullPath = classFile.getAbsolutePath();
final File changedFileOutput = new File(changedFileInputFullPath.replace(input.getAbsolutePath(), output.getAbsolutePath()));
if (changedFileOutput.getCanonicalPath().equals(classFile.getCanonicalPath())) {
throw new RuntimeException("Input file(" + classFile.getCanonicalPath() + ") should not be same with output!");
}
if (!changedFileOutput.exists()) {
changedFileOutput.getParentFile().mkdirs();
}
changedFileOutput.createNewFile();
if (MethodCollector.isNeedTraceFile(classFile.getName())) {
is = new FileInputStream(classFile);
ClassReader classReader = new ClassReader(is);
ClassWriter classWriter = new TraceClassWriter(ClassWriter.COMPUTE_FRAMES, classLoader);
ClassVisitor classVisitor = new TraceClassAdapter(AgpCompat.getAsmApi(), classWriter);
classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
is.close();
byte[] data = classWriter.toByteArray();
View on GitHub (pinned to 3b8293bd65)