SubtitleEdit/subtitleedit · error · InvalidOperationException

VlcPlayer is not initialized

Error message

VlcPlayer is not initialized

What it means

Thrown by LibVlcDynamicSoftwareControl.OnInitialized() if the _vlcPlayer field is null when Avalonia raises the Initialized event. The field is assigned in the constructor from a non-nullable parameter, so under normal use it is never null here. This guard catches two abnormal cases: the control was constructed by passing null (a nullable-reference violation by the caller), or the control was detached (OnDetachedFromVisualTree sets _vlcPlayer = null) and then re-initialized in the same lifecycle.

Source

Thrown at src/ui/Logic/VideoPlayers/LibVlcDynamic/LibVlcDynamicSoftwareControl.cs:44

    private int _frameWidth;
    private int _frameHeight;

    public LibVlcDynamicPlayer? Player => _vlcPlayer;

    public LibVlcDynamicSoftwareControl(LibVlcDynamicPlayer vlcPlayer)
    {
        _vlcPlayer = vlcPlayer;
        ClipToBounds = true;
        Cursor = new Cursor(StandardCursorType.Arrow);
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();

        if (_vlcPlayer == null)
        {
            throw new InvalidOperationException("VlcPlayer is not initialized");
        }

        System.Diagnostics.Debug.WriteLine("Initializing VlcPlayer with software rendering");

        try
        {
            _vlcPlayer.LoadLib();
            _vlcPlayer.PlayerSubName = "sw";
            SetupVideoCallbacks();
            _isInitialized = true;
            System.Diagnostics.Debug.WriteLine("VlcPlayer initialized successfully with software rendering!");
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"Failed to initialize VlcPlayer: {ex.Message}");
        }
    }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Always construct LibVlcDynamicSoftwareControl with a non-null LibVlcDynamicPlayer obtained from the video-player factory.
  2. Do not re-use a control instance after it has been detached — create a new LibVlcDynamicPlayer + control pair on each attach.
  3. In DI/factory code, assert the resolved player is non-null before constructing the control.
  4. If the player can legitimately be unavailable, branch on that before creating the control rather than passing null.

Example fix

// before: factory may hand back null and the control is built anyway
var player = ResolvePlayer();
var control = new LibVlcDynamicSoftwareControl(player!);

// after: fail fast at the factory boundary, never let null reach the control
var player = ResolvePlayer() ?? throw new InvalidOperationException("No LibVlcDynamicPlayer available.");
var control = new LibVlcDynamicSoftwareControl(player);
Defensive patterns

Strategy: validation

Validate before calling

// Guarantee a non-null player before the control is created.
var player = playerFactory.Create()
    ?? throw new InvalidOperationException("No LibVlcDynamicPlayer available for software control.");
var control = new LibVlcDynamicSoftwareControl(player);

// Optional: assert at attach time if you re-host controls.
if (control.Player is null)
{
    throw new InvalidOperationException("Cannot host a software control without a player.");
}

Prevention

When it happens

Trigger: OnInitialized() fires after the Avalonia control is added to the logical tree. The throw occurs if _vlcPlayer is null at that point — either because 'new LibVlcDynamicSoftwareControl(null!)' was used, or because OnDetachedFromVisualTree already nulled the field (line 156) and the control is being re-hosted without a fresh instance.

Common situations: A caller bypasses the constructor contract and passes null (often from a DI/factory path that returned null); XAML/code re-parents the same control instance after detach, hitting Initialized again on a disposed player; a test instantiates the control without supplying a player. The downstream LoadLib/SetupVideoCallbacks would NRE without this explicit guard.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/de5cc6ca20fb2863. Report an issue: GitHub.