JanDeDobbeleer/oh-my-posh · error

RoInitialize: 0x%08x

Error message

RoInitialize: 0x%08x

What it means

Before touching any WinRT API, the SMTC media player code calls RoInitialize with RO_INIT_MULTITHREADED on the locked OS thread. S_FALSE (1) means the thread was already initialized and is accepted; any other non-zero HRESULT is returned as this error, meaning WinRT could not be initialized on this thread and no media info can be queried.

Source

Thrown at src/runtime/smtc_windows.go:229

		}
		if time.Now().After(deadline) {
			return errors.New("async timed out")
		}
		time.Sleep(smtcAsyncPollInterval)
	}
}

func queryMediaPlayer(player string) (*MediaInfo, error) {
	// RoInitialize / RoUninitialize update thread-local state, so we have to
	// pin the goroutine to one OS thread for the duration of this call.
	goruntime.LockOSThread()
	defer goruntime.UnlockOSThread()

	// RO_INIT_MULTITHREADED = 1. S_FALSE (1) means already initialised on
	// this thread, which is fine — we still pair with RoUninitialize.
	hr, _, _ := procRoInitialize.Call(1)
	if hr != 0 && hr != 1 {
		return nil, fmt.Errorf("RoInitialize: 0x%08x", hr)
	}
	defer func() { _, _, _ = procRoUninitialize.Call() }()

	classID, err := newHString("Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager")
	if err != nil {
		return nil, err
	}
	defer classID.Close()

	var factory unsafe.Pointer
	hr, _, _ = procRoGetActivationFactory.Call(
		uintptr(classID),
		uintptr(unsafe.Pointer(&iidSMTCSessionManagerStatics)),
		uintptr(unsafe.Pointer(&factory)),
	)
	if hr != 0 {
		return nil, fmt.Errorf("RoGetActivationFactory: 0x%08x", hr)
	}

View on GitHub (pinned to 0976794618)

Solutions

  1. If the HRESULT is 0x80010106 (E_CHANGEDMODE), run the prompt in a thread/process that has not pre-initialized COM as STA, or accept the media segment being unavailable
  2. Retry after freeing memory if the code is E_OUTOFMEMORY
  3. Check the host application's COM apartment model if embedding oh-my-posh
  4. Update Windows if the failure persists on a clean thread
Defensive patterns

Strategy: fallback

Try / catch

info, err := runtime.QueryMediaPlayer(env)
if err != nil {
	var hrErr interface{ HRESULT() uint32 }
	if errors.As(err, &hrErr) { /* inspect RoInitialize HRESULT */ }
	return mediaSegment{} // hide segment, prompt keeps rendering
}

Prevention

When it happens

Trigger: QueryMediaPlayer calling procRoInitialize and getting an HRESULT other than 0 (S_OK) or 1 (S_FALSE) - e.g. E_OUTOFMEMORY (0x8007000E) or E_CHANGEDMODE (0x80010106) when the thread is already initialized in a different apartment mode.

Common situations: Embedding oh-my-posh in a host process that already initialized COM on the thread as STA (single-threaded apartment); extremely low-memory conditions (E_OUTOFMEMORY); unusual threading environments in custom prompt hosts.

Related errors


AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31). Data as JSON: /api/errors/ad3b96409ed61ea0. Report an issue: GitHub.