{"record":{"id":"e76e718bd9143c69","repo":"stride3d/stride","slug":"seek-failed-mediacodecscheduler-is-null","errorCode":null,"errorMessage":"Seek failed: MediaCodecScheduler is null","messagePattern":"Seek failed: MediaCodecScheduler is null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Video/Backends/MediaCodecVideoBackend.cs","lineNumber":173,"sourceCode":"        mediaSynchronizer.Play();\n    }\n\n    public override void Pause()\n    {\n        if (mediaSynchronizer == null)\n            throw new InvalidOperationException(\"PauseMedia failed: MediaCodecScheduler is null\");\n        mediaSynchronizer.Pause();\n    }\n\n    public override void Stop()\n    {\n        mediaSynchronizer.Stop();\n    }\n\n    public override void Seek(TimeSpan time)\n    {\n        if (mediaSynchronizer == null)\n            throw new InvalidOperationException(\"Seek failed: MediaCodecScheduler is null\");\n        mediaSynchronizer.Seek(time);\n    }\n\n    public override void SetPlaybackSpeed(float speed) => mediaSynchronizer.SpeedFactor = speed;\n\n    public override void SetAudioVolume(float volume)\n    {\n        if (audioSoundInstance != null)\n            audioSoundInstance.Volume = volume;\n        foreach (var controller in audioControllers)\n            controller.Volume = volume;\n    }\n\n    public override void UpdatePlayRange() => mediaSynchronizer.PlayRange = Instance.PlayRange;\n\n    public override void UpdateLoopRange()\n    {\n        mediaSynchronizer.IsLooping = Instance.IsLooping;","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Video/Backends/MediaCodecVideoBackend.cs#L155-L191","documentation":"Thrown by MediaCodecVideoBackend.Seek when the underlying media synchronizer has not been created (or has been released) when a seek is requested. The library treats a seek on an un-initialized/disposed backend as a programming error, so it throws immediately rather than silently ignoring the request. The message mentions 'MediaCodecScheduler' (the synchronizer/scheduler object) even though the guard checks mediaSynchronizer.","triggerScenarios":"Calling Seek(TimeSpan) before the backend finished initialization (mediaSynchronizer still null), or after the backend was torn down and mediaSynchronizer.Stop()/release paths nulled it. Any code path that reaches Seek without a successful Initialize is affected.","commonSituations":"UI seek-bar handlers firing before video playback is ready; calling Seek on a video component whose Load failed earlier; seeking after Dispose due to a race between teardown and user input; platform where Initialize aborted early but the control is still interactive.","solutions":["Ensure Initialize completed successfully before wiring UI seek handlers to the backend","Guard Seek call sites: only call when the backend reports it is initialized/playing","Check that teardown/Dispose nulls or blocks Seek, and unsubscribe UI events on dispose","Catch InvalidOperationException around Seek and ignore/log if not yet initialized"],"exampleFix":"// before\nvideoBackend.Seek(newPosition); // may throw if not initialized\n// after\nif (videoBackend.IsInitialized)\n    videoBackend.Seek(newPosition);\nelse\n    Logger.Warning(\"Seek ignored: backend not initialized\");","handlingStrategy":"try-catch","validationCode":"if (videoBackend == null || !videoBackend.IsInitialized)\n    return; // don't attempt to seek yet","typeGuard":"static bool CanSeek(MediaCodecVideoBackend b) => b is { } && b.IsInitialized && !b.IsDisposed;","tryCatchPattern":"try\n{\n    videoBackend.Seek(position);\n}\ncatch (InvalidOperationException)\n{\n    Logger.Warning(\"Seek before backend ready; ignoring\");\n}","preventionTips":["Only enable seek UI after the backend signals readiness","Unsubscribe input/seek handlers in Dispose to avoid post-teardown seeks","Track initialization state centrally so components query one source of truth"],"tags":["video","media-playback","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}