NationalSecurityAgency/ghidra · error · IOException

Null datatype passed to getIsfObject

Error message

Null datatype passed to getIsfObject

What it means

IOException('Null datatype passed to getIsfObject') thrown at the top of IsfDataTypeWriter.getIsfObject when dt == null. The writer cannot serialize a null DataType to ISF JSON, so it fails fast. Note it only guards null; FactoryDataType and BitFieldDataType are logged as errors but not thrown.

Source

Thrown at Ghidra/Debug/Debugger-isf/src/main/java/ghidra/program/model/data/ISF/IsfDataTypeWriter.java:374

			resolved.put(dt, isf);
			return jobj;
		}
		return null;
	}

	/**
	 * Writes the data type as ISF JSON using the underlying writer. For now,
	 * ignoring top-level bit-fields and function defs as unsupported by ISF.
	 * Typedefs really deserve their own category, but again unsupported.
	 * 
	 * @param dt      the data type to write as ISF JSON
	 * @param monitor the task monitor
	 * @throws IOException if there is an exception writing the output
	 */
	protected IsfObject getIsfObject(DataType dt, TaskMonitor monitor)
			throws IOException, CancelledException {
		if (dt == null) {
			throw new IOException("Null datatype passed to getIsfObject");
		}
		if (dt instanceof FactoryDataType) {
			Msg.error(this, "Factory data types may not be written - type: " + dt);
		}
		if (dt instanceof BitFieldDataType) {
			Msg.error(this, "BitField data types may not be written - type: " + dt);
		}
		if (dt instanceof Pointer || dt instanceof Array) {
			IsfObject type = getObjectDataType(IsfUtilities.getBaseDataType(dt));
			IsfObject obj = newTypedObject(dt, type);
			return obj;
		}

		dt = dt.clone(dtm); // force resize/repack for target data organization

		IsfObject res = resolve(dt);
		if (res != null) {
			return res;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Filter null data types out of the input set before iterating and calling getIsfObject.
  2. Resolve/validate each DataType is non-null (and not a FactoryDataType/BitFieldDataType if those are unsupported for your export) before writing.
  3. Log which category/path produced the null so the unresolved type can be fixed in the program/archive.

Example fix

// before
for (DataType dt : types) {
    IsfObject o = writer.getIsfObject(dt, monitor);
}

// after
for (DataType dt : types) {
    if (dt == null) {
        Msg.warn(this, "Skipping null data type during ISF export");
        continue;
    }
    IsfObject o = writer.getIsfObject(dt, monitor);
}
Defensive patterns

Strategy: type-guard

Validate before calling

for (DataType dt : types) {
    if (dt == null) continue;
    writer.getIsfObject(dt, monitor);
}

Type guard

boolean isWritable(DataType dt) {
    return dt != null
        && !(dt instanceof FactoryDataType)
        && !(dt instanceof BitFieldDataType);
}

Try / catch

try {
    writer.getIsfObject(dt, monitor);
} catch (IOException e) {
    if (e.getMessage().contains("Null datatype")) {
        // skip null entries in the export set
    }
}

Prevention

When it happens

Trigger: getIsfObject(dt, monitor) is called with a null DataType, e.g. a category/typedef resolution returning null, a list iteration containing a null entry, or an unresolved dependent type passed straight through.

Common situations: Walking a data type manager where some referenced types are unresolved (null); scripted export feeding a filtered list that includes nulls; pointer/array base type resolution returning null via IsfUtilities.getBaseDataType before newTypedObject is built.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/1eb3f06516aa9906. Report an issue: GitHub.