`snappy` Copy Bands does not copy data

I’m trying to use snappy to handle reading data from a file, processing it in with numpy, and then saving in a new product. I’ve successfully been able to read data from a band to a numpy array, process it, and the write it to a new data file. But I can’t seem to manage to copy over the other bands. In the .dim file they are defined, but the .img and .hdr files are not added to the .data folder.

I’ve put together a MRE here. What am I missing?

import os
from shutil import rmtree

import esa_snappy
import jpy

from esa_snappy import ProductIO, ProductUtils, VirtualBand


try:
    rmtree("tmp/S1A_IW_SLC__1SDV_20250211T132805_20250211T132832_057849_0722A7_E32D_Orb_Stack_ifg_fltpy.data")
except FileNotFoundError:
    pass
try:
    os.unlink(
        "tmp/S1A_IW_SLC__1SDV_20250211T132805_20250211T132832_057849_0722A7_E32D_Orb_Stack_ifg_fltpy.dim")
except FileNotFoundError:
    pass


def process() -> None:

    p = ProductIO.readProduct(
        "tmp/S1A_IW_SLC__1SDV_20250211T132805_20250211T132832_057849_0722A7_E32D_Orb_Stack_ifg.dim")

    # often the target product dimensions are the same as the source product dimensions
    width = p.getSceneRasterWidth()
    height = p.getSceneRasterHeight()
    target_product = esa_snappy.Product(
        f"{p.getName()}_fltpy", p.getProductType(), width, height)

    ProductUtils.copyGeoCoding(p, target_product)

    # Copy over everything besides the bands (metadata, vector data, masks, etc)
    ProductUtils.copyProductNodes(p, target_product)

    # 3. Set product writer
    target_product.setProductWriter(ProductIO.getProductWriter("BEAM-DIMAP"))

    target_product.writeHeader(
        "tmp/S1A_IW_SLC__1SDV_20250211T132805_20250211T132832_057849_0722A7_E32D_Orb_Stack_ifg_fltpy.dim")

    for band in target_product.getBands():
        vb = jpy.cast(band, VirtualBand)
        if isinstance(vb, VirtualBand):
            ProductUtils.copyVirtualBand(target_product, vb, vb.getName())
        else:
            ProductUtils.copyBand(band.getName(), p, target_product, True)

    target_product.closeIO()


process()