zed-industries/zed · error

GlobalLock returned null

Error message

GlobalLock returned null

What it means

Sentinel guard in `set_clipboard_bytes` (called by write_string/write_image) raised when the Win32 `GlobalLock` on the freshly allocated global memory returns null, meaning the HGLOBAL could not be locked to copy clipboard payload into it (typically out-of-memory or an invalid/zeroed handle).

Source

Thrown at crates/gpui_windows/src/clipboard.rs:154

        let filename_length = unsafe { DragQueryFileW(hdrop, file_index, None) } as usize;
        let mut buffer = vec![0u16; filename_length + 1];
        let ret = unsafe { DragQueryFileW(hdrop, file_index, Some(buffer.as_mut_slice())) };
        if ret == 0 {
            log::error!("unable to read file name of dragged file");
            continue;
        }
        match String::from_utf16(&buffer[0..filename_length]) {
            Ok(file_name) => f(file_name),
            Err(e) => log::error!("dragged file name is not UTF-16: {}", e),
        }
    }
}

fn set_clipboard_bytes<T>(data: &[T], format: u32) -> Result<()> {
    unsafe {
        let global = Owned::new(GlobalAlloc(GMEM_MOVEABLE, std::mem::size_of_val(data))?);
        let ptr = GlobalLock(*global);
        anyhow::ensure!(!ptr.is_null(), "GlobalLock returned null");
        std::ptr::copy_nonoverlapping(data.as_ptr(), ptr as _, data.len());
        GlobalUnlock(*global).ok();
        SetClipboardData(format, Some(HANDLE(global.0)))?;
        // SetClipboardData succeeded — the system now owns the memory.
        std::mem::forget(global);
    }
    Ok(())
}

fn get_clipboard_string(format: u32) -> Option<String> {
    let locked = get_clipboard_data(format)?;
    let bytes = locked.as_bytes();
    let words_len = bytes.len() / std::mem::size_of::<u16>();
    if words_len == 0 {
        return Some(String::new());
    }
    let slice = unsafe { std::slice::from_raw_parts(bytes.as_ptr() as *const u16, words_len) };
    let actual_len = slice.iter().position(|&c| c == 0).unwrap_or(words_len);

View on GitHub (pinned to f4178619ac)

Solutions

  1. Retry the GlobalAlloc/GlobalLock sequence; transient low-memory conditions can clear.
  2. Check GlobalAlloc's return before locking to avoid locking an invalid handle.
  3. Reduce the payload size (large images) if memory pressure is the cause.
  4. Free the failed HGLOBAL with GlobalFree to avoid a leak before returning the error.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at crates/gpui_windows/src/clipboard.rs:154 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/d2c03f7866b3f3b5. Report an issue: GitHub.