{"record":{"id":"99249e98d7777dea","repo":"NationalSecurityAgency/ghidra","slug":"zero-length-data-not-allowed-origtype-getname","errorCode":null,"errorMessage":"Zero-length data not allowed {origType.getName}","messagePattern":"Zero-length data not allowed (.+?)","errorType":"exception","errorClass":"CodeUnitInsertionException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceDefinedDataView.java","lineNumber":128,"sourceCode":"\t\t\t\tlength = dataType.getLength();\n\t\t\t}\n\t\t\telse if (dataType instanceof Dynamic) {\n\t\t\t\t// TODO: Should I consider no observations to be \"uninitialized\"?\n\t\t\t\t// If so, dynamic types cannot be applied here\n\t\t\t\tDynamic dyn = (Dynamic) dataType;\n\t\t\t\tMemBuffer buffer = memSpace.getBufferAt(startSnap, address);\n\t\t\t\tlength = dyn.getLength(buffer, length);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlength = dataType.getLength();\n\t\t\t}\n\n\t\t\tif (length < 0) {\n\t\t\t\tthrow new CodeUnitInsertionException(\n\t\t\t\t\t\"Failed to resolve data length for \" + origType.getName());\n\t\t\t}\n\t\t\tif (length == 0) {\n\t\t\t\tthrow new CodeUnitInsertionException(\n\t\t\t\t\t\"Zero-length data not allowed \" + origType.getName());\n\t\t\t}\n\n\t\t\tAddress endAddress = address.addNoWrap(length - 1);\n\t\t\tAddressRangeImpl createdRange = new AddressRangeImpl(address, endAddress);\n\n\t\t\t// Truncate, then check that against existing code units.\n\t\t\tlong endSnap = computeTruncatedMax(lifespan, null, createdRange);\n\t\t\tTraceAddressSnapRange tasr =\n\t\t\t\tnew ImmutableTraceAddressSnapRange(createdRange, Lifespan.span(startSnap, endSnap));\n\t\t\tif (!space.undefinedData.coversRange(tasr)) {\n\t\t\t\t// TODO: Figure out the conflicting unit?\n\t\t\t\tthrow new CodeUnitInsertionException(\"Code units cannot overlap\");\n\t\t\t}\n\n\t\t\tif (dataType == DataType.DEFAULT) {\n\t\t\t\treturn space.undefinedData.getAt(startSnap, address);\n\t\t\t}","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceDefinedDataView.java#L110-L146","documentation":"Thrown by DBTraceDefinedDataView.create() when the resolved data length is exactly 0. A zero-length data unit has no address range and is semantically meaningless, so the model rejects it. This can happen when a data type's getLength() returns 0, or when a Dynamic type's getLength(buffer, length) computes 0 (e.g., an empty structure or a string type that finds an immediate terminator).","triggerScenarios":"Calling create() where the final computed length == 0. This occurs with empty composites, Dynamic types that resolve to zero bytes (e.g., TerminatedStringDataType over a single null byte), or when origLength is explicitly passed as 0 for a fixed type.","commonSituations":"Applying a string type to an address that contains only a null terminator; empty struct definitions; explicitly passing 0 as length; Dynamic type whose computed length collapses to zero on specific byte patterns.","solutions":["Ensure the data type and memory produce a non-zero length — check dataType.getLength() or the Dynamic result before creating.","Use a minimum-length data type (e.g., ByteDataType for a single byte) instead.","If applying a string type, ensure there is at least one non-terminator byte at the address.","Validate: if computed length == 0, skip the create call or log a warning."],"exampleFix":"// before\nview.create(lifespan, address, platform, TerminatedStringDataType.dataType);\n// address has only \\x00 — length resolves to 0\n\n// after — ensure meaningful bytes, or use a different type\nif (memSpace.getByte(snap, address) != 0) {\n    view.create(lifespan, address, platform, TerminatedStringDataType.dataType);\n} else {\n    view.create(lifespan, address, platform, ByteDataType.dataType);\n}","handlingStrategy":"validation","validationCode":"// Compute and check length before creating\nint expectedLength = (dataType instanceof Dynamic dyn)\n    ? dyn.getLength(memSpace.getBufferAt(startSnap, address), dataType.getLength())\n    : dataType.getLength();\nif (expectedLength == 0) {\n    // Zero-length not allowed — use a minimum-size type or skip\n    return;\n}\nview.create(lifespan, address, platform, dataType, expectedLength);","typeGuard":null,"tryCatchPattern":"try {\n    view.create(lifespan, address, platform, dataType, length);\n} catch (CodeUnitInsertionException e) {\n    if (e.getMessage().startsWith(\"Zero-length data not allowed\")) {\n        // Use a minimal fixed type instead\n        view.create(lifespan, address, platform, ByteDataType.dataType, 1);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check that computed length > 0 before creating data units.","For string types, verify at least one non-terminator byte exists at the address.","Avoid empty struct definitions — ensure composites have at least one field."],"tags":["data-type","zero-length","create","trace-modeling"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}