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
- Update/clean-reinstall GPU drivers
- Disable overlay/recording software that may hook d3d11.dll and retry
- Run `sfc /scannow` to verify d3d11.dll integrity
- Log the descriptor (size/format) that triggered it to rule out a degenerate request
- 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
- Treat silent nulls as a session-level fault and restart the WGC capture
- Check for DLL hooks on d3d11.dll in affected environments
- Keep GPU drivers clean and current
- Log the descriptor alongside the failure for reproducibility
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
- CreateTexture2D: {}
- D3D11CreateDevice returned no device
- CreateDirect3D11DeviceFromDXGIDevice failed: {}
- GetImmediateContext failed: {}
- cast D3D11 device to IDXGIDevice failed: {}
AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01).
Data as JSON: /api/errors/94ee012462f5dde1.
Report an issue: GitHub.