# How to Debug ID Collision Issues Using the ImGui ID Stack Tool

> Debug ImGui ID collision issues effectively. Learn how the ImGui ID Stack Tool visualizes intermediate hashes to pinpoint problematic PushID calls or string literals causing duplicate ImGuiIDs. Resolve warnings efficiently.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-16

---

**The ImGui ID Stack Tool visualizes every intermediate hash value that contributes to a widget's final 32-bit identifier, allowing you to trace exactly which `PushID` calls or string literals cause two widgets to receive the same `ImGuiID` and trigger collision warnings.**

Dear ImGui (ocornut/imgui) generates unique 32-bit identifiers for every widget by hashing a hierarchical stack of strings, integers, and pointers. When two widgets accidentally receive the same hash, the library flags the conflict via `DebugDrawIdConflictsId`, but tracing the root cause requires inspecting the full ID stack. The **ID Stack Tool** provides this visibility, showing each step of the hash computation in a tree view.

## Understanding ImGui ID Collisions

Every widget in Dear ImGui receives an `ImGuiID` created by hashing the current ID stack. The stack typically includes window names, `PushID` calls, and implicit string labels. When the hash function produces identical values for two different widgets, ImGui draws a red outline around the conflicting items and sets the internal `DebugDrawIdConflictsId` variable to flag the collision.

Without visibility into the intermediate hash values, resolving these conflicts is guesswork. The collision warning tells you that two widgets share an ID, but not which specific `PushID` calls or string literals created the duplicate.

## How the ID Stack Tool Works

The tool is powered by the `ImGuiIDStackTool` structure defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) (lines 2214–2222), which stores inspection options including hex-encoding and clipboard handling. It operates through a hook mechanism: when you set `DebugHookIdInfoId` (line 2306) to a specific ID, all `GetID*` functions call `ImGui::DebugHookIdInfo()` whenever they generate a matching identifier.

This hook feeds the tool with stack-level details using `ImGuiDataType_*` identifiers, revealing how each `PushID`, `PushOverrideID`, or pointer contributed to the final hash. The result is a tree view where each node represents one step of the hash computation, from the root window down to the final widget ID.

## Opening the ID Stack Tool

You can activate the tool through the Demo menu or programmatically.

**Via the Demo Menu:**
Navigate to **Demo > Tools > ID Stack Tool** to open the inspection window.

**Programmatically:**
Call `ImGui::ShowIDStackToolWindow()` from your code to open the tool directly, which is useful when building debugging utilities:

```cpp
if (ImGui::Button("Show ID Stack"))
    ImGui::ShowIDStackToolWindow();

```

According to the implementation in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) (around line 18367), this function creates the tool window and initializes the inspection state.

## Tracing ID Collisions

When an ID collision occurs, hover over the widget displaying the red conflict outline. The ID Stack Tool automatically selects that ID and displays the full hash stack.

The tree view reveals:
- Each `PushID` call with its associated string or integer value
- Any `PushOverrideID` calls that may have disrupted the hash sequence
- Pointer values that contributed to the hash

**Common Collision Patterns:**
- **Duplicate string literals:** Reusing the same label (e.g., `"OK"`) inside different parent scopes without an additional `PushID` creates identical hashes.
- **Override conflicts:** Calling `PushOverrideID(0)` where the underlying hash would otherwise be unique.
- **Dynamic index collisions:** Mixing static IDs like `ImGui::GetID("Button")` with dynamic data (e.g., array indices that reset each frame) causing unintended hash repetitions.

## Resolving Collisions

Once the tool identifies which stack level causes the duplication, wrap the conflicting widgets in unique `PushID` scopes:

```cpp
// Problem: Both buttons share the same implicit ID
if (ImGui::Button("OK")) { /* ... */ }
ImGui::SameLine();
if (ImGui::Button("OK")) { /* ... */ }  // Collision: same hash("OK")

// Solution: Add explicit PushID scopes
ImGui::PushID("DialogA");
if (ImGui::Button("OK")) { /* ... */ }  // ID = hash("DialogA", "OK")
ImGui::PopID();

ImGui::PushID("DialogB");
if (ImGui::Button("OK")) { /* ... */ }  // ID = hash("DialogB", "OK")
ImGui::PopID();

```

For manual investigation of a specific ID flagged by `DebugDrawIdConflictsId`, you can force the tool to inspect it directly:

```cpp
ImGuiID problematic_id = g.DebugDrawIdConflictsId;    // ID flagged by ImGui
ImGui::DebugHookIdInfoId = problematic_id;           // Force the tool to follow this ID

```

## Summary

- **ImGui ID collisions** occur when two widgets generate identical 32-bit hashes from the ID stack, triggering red outlines and setting `DebugDrawIdConflictsId`.
- The **ID Stack Tool** (defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) lines 2214–2222) visualizes every intermediate hash step via the `DebugHookIdInfo` hook mechanism.
- Open the tool via **Demo > Tools > ID Stack Tool** or by calling `ImGui::ShowIDStackToolWindow()` (implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) around line 18367).
- Hover over colliding widgets to auto-select their ID, then examine the stack to identify duplicate `PushID` values or conflicting string literals.
- Fix collisions by adding unique `PushID` scopes or changing the data used to generate widget identifiers.

## Frequently Asked Questions

### How do I know if my ImGui widgets have ID collisions?

When two active widgets share the same `ImGuiID`, Dear ImGui draws a red outline around the conflicting widgets and sets the internal `DebugDrawIdConflictsId` variable to the problematic hash value. You will see visual distortion in the UI and can check the global debug state to confirm the collision ID.

### What is the ImGuiIDStackTool structure used for?

The `ImGuiIDStackTool` structure (defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) at lines 2214–2222) stores the internal state for the ID Stack Tool, including the currently inspected ID, display options for hex-encoding, and clipboard export settings. It powers the visualization that shows how each `PushID` and string literal contributes to the final widget hash.

### Can I programmatically force the ID Stack Tool to inspect a specific widget?

Yes. Set the `ImGui::DebugHookIdInfoId` global to the target `ImGuiID` (for example, the value stored in `DebugDrawIdConflictsId`). The next time the UI generates that ID, the `DebugHookIdInfo` function will capture the full stack trace and display it in the tool window.

### Where can I find example code for using the ID Stack Tool?

The official demo code in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) contains examples showing how to call `ImGui::ShowIDStackToolWindow()` and demonstrates ID conflict visualization. Additionally, the [`docs/FAQ.md`](https://github.com/ocornut/imgui/blob/main/docs/FAQ.md) file provides a brief user guide mentioning the tool's location in the Demo menu.