screenpipe/screenpipe · error · anyhow::Error

CreateTexture2D returned no texture

Error message

CreateTexture2D returned no texture

What it means

This is the companion null-check for [553]: `CreateTexture2D` returned S_OK but left the output texture pointer null. Since downstream code (CopyResource, Map) cannot tolerate a null texture, `create_texture_like` converts it into an explicit error. It is a defensive invariant check that rarely fires; when it does, it points to a device/runtime anomaly.

Source

Thrown at crates/screenpipe-screen/src/wgc_capture.rs:329

fn create_texture_like(
    device: &ID3D11Device,
    src_desc: &D3D11_TEXTURE2D_DESC,
    usage: D3D11_USAGE,
    cpu_access_flags: u32,
) -> Result<ID3D11Texture2D> {
    let mut desc = *src_desc;
    desc.Usage = usage;
    desc.BindFlags = 0;
    desc.CPUAccessFlags = cpu_access_flags;
    desc.MiscFlags = 0;

    let mut texture = None;
    unsafe {
        device
            .CreateTexture2D(&desc, None, Some(&mut texture))
            .map_err(|e| anyhow!("CreateTexture2D: {}", e))?;
    }
    texture.ok_or_else(|| anyhow!("CreateTexture2D returned no texture"))
}

extern "system" fn monitor_enum_proc(
    h_monitor: HMONITOR,
    _hdc: HDC,
    _rect: *mut RECT,
    state: LPARAM,
) -> BOOL {
    unsafe {
        (*(state.0 as *mut Vec<HMONITOR>)).push(h_monitor);
    }
    TRUE
}

/// Resolve a live `HMONITOR` for `monitor_id` (xcap's monitor id is `HMONITOR.0 as u32`).
/// Re-enumerating (rather than reconstructing the pointer from the id) makes sure the
/// handle is still valid right now, matching how the rest of this crate resolves ids.
fn find_hmonitor(monitor_id: u32) -> Result<HMONITOR> {

View on GitHub (pinned to 4ebf712990)

Solutions

  1. Update/clean-reinstall GPU drivers
  2. Disable overlay/recording software that may hook d3d11.dll and retry
  3. Run `sfc /scannow` to verify d3d11.dll integrity
  4. Log the descriptor (size/format) that triggered it to rule out a degenerate request
  5. Treat as fatal for the capture session and restart the WGC capture
Defensive patterns

Strategy: try-catch

Try / catch

match create_texture_like(&device, &src_desc, staging) {
    Err(e) if e.to_string().contains("returned no texture") => {
        // environment anomaly: restart session, flag d3d11.dll hooking
        eprintln!("CreateTexture2D silently failed; restarting capture session");
        restart_capture_session();
    }
    Ok(t) => { /* use texture */ }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `device.CreateTexture2D(&desc, None, Some(&mut texture))` reports success but `texture` stays `None`, reached from `store_frame` or `readback` — e.g. under DLL hooking of d3d11.dll or a broken driver that fakes success.

Common situations: Same environments as [553]: hooked d3d11.dll (overlays/AV), corrupt driver installations, or exotic third-party graphics-stack shims that return success without creating the object.

Related errors


AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01). Data as JSON: /api/errors/94ee012462f5dde1. Report an issue: GitHub.