skylot/jadx · error · JadxRuntimeException

Unknown file format:

Error message

Unknown file format: 

What it means

Thrown by ClsSet.save(Path) when the output file path does not end with the .jcst extension (CLST_EXTENSION). The save method only supports writing the jadx class set binary format to files with this specific extension; any other extension is rejected before serialization begins. This is a pure validation check on the output path.

Source

Thrown at jadx-core/src/main/java/jadx/core/clsp/ClsSet.java:196

	}

	private static ClspClass getCls(String fullName, Map<String, ClspClass> names) {
		ClspClass cls = names.get(fullName);
		if (cls == null) {
			LOG.debug("Class not found: {}", fullName);
		}
		return cls;
	}

	public void save(Path path) throws IOException {
		FileUtils.makeDirsForFile(path);
		String outputName = path.getFileName().toString();
		if (outputName.endsWith(CLST_EXTENSION)) {
			try (BufferedOutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(path))) {
				save(outputStream);
			}
		} else {
			throw new JadxRuntimeException("Unknown file format: " + outputName);
		}
	}

	private void save(OutputStream output) throws IOException {
		DataOutputStream out = new DataOutputStream(output);
		out.writeBytes(JADX_CLS_SET_HEADER);
		out.writeByte(VERSION);
		out.writeInt(androidApiLevel);

		Map<String, ClspClass> names = new HashMap<>(classes.length);
		out.writeInt(classes.length);
		for (ClspClass cls : classes) {
			out.writeInt(cls.getAccFlags());
			writeUnsignedByte(out, cls.getSource().ordinal());
			String clsName = cls.getName();
			writeString(out, clsName);
			names.put(clsName, cls);
		}

View on GitHub (pinned to e738a26571)

Solutions

  1. Ensure the output path ends with exactly '.jcst' (lowercase).
  2. If building the path dynamically, append CLST_EXTENSION (or ".jcst") to the filename.
  3. Catch JadxRuntimeException around ClsSet.save and report the expected extension to the user.

Example fix

// before
clsSet.save(Path.of("/tmp/classpath-export"));

// after
clsSet.save(Path.of("/tmp/classpath-export.jcst"));
Defensive patterns

Strategy: validation

Validate before calling

// Validate the output path ends with .jcst before calling save
if (!outputPath.getFileName().toString().endsWith(".jcst")) {
    throw new IllegalArgumentException(
        "Output path must end with .jcst, got: " + outputPath.getFileName());
}
clsSet.save(outputPath);

Type guard

static boolean isValidJcstPath(Path path) {
    String name = path.getFileName().toString();
    return name.endsWith(".jcst");
}

Prevention

When it happens

Trigger: Calling ClsSet.save(path) where path.getFileName() does not end with '.jcst'. For example, passing a .json, .bin, or extensionless path. The check is case-sensitive and exact — '.JCST' or '.jcst.bak' would also fail.

Common situations: Programmatic callers that construct the output path dynamically and forget the extension. CLI or scripting workflows that pass an arbitrary output filename. Copy-paste errors where a different file extension is used.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/1feb49728a0ca0a2. Report an issue: GitHub.