bilibili/flv.js · error · IllegalStateException
HTMLMediaElement must be attached before load()!
Error message
HTMLMediaElement must be attached before load()!
What it means
FlvPlayer.load() requires an HTMLMediaElement to have been attached via attachMediaElement() first, because MSECTL and the media element wiring are created during attachment. Calling load() without attachment throws IllegalStateException so the pipeline is not started against a missing output.
Source
Thrown at src/player/flv-player.js:189
detachMediaElement() {
if (this._mediaElement) {
this._msectl.detachMediaElement();
this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);
this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);
this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);
this._mediaElement.removeEventListener('stalled', this.e.onvStalled);
this._mediaElement.removeEventListener('progress', this.e.onvProgress);
this._mediaElement = null;
}
if (this._msectl) {
this._msectl.destroy();
this._msectl = null;
}
}
load() {
if (!this._mediaElement) {
throw new IllegalStateException('HTMLMediaElement must be attached before load()!');
}
if (this._transmuxer) {
throw new IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');
}
if (this._hasPendingLoad) {
return;
}
if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {
this._hasPendingLoad = true;
return;
}
if (this._mediaElement.readyState > 0) {
this._requestSetTime = true;
// IE11 may throw InvalidStateError if readyState === 0
this._mediaElement.currentTime = 0;
}View on GitHub (pinned to 42343088f2)
Solutions
- Call player.attachMediaElement(videoElement) before player.load().
- Reorder code so load() runs after the media element exists in the DOM.
- If load() may be invoked from multiple places, check player._mediaElement or wrap in try/catch for IllegalStateException.
Example fix
// before
const player = flvjs.createPlayer(source);
player.load();
// after
const player = flvjs.createPlayer(source);
player.attachMediaElement(document.querySelector('video'));
player.load(); Defensive patterns
Strategy: validation
Validate before calling
function safeLoad(player, videoEl) {
if (!videoEl || !(videoEl instanceof HTMLMediaElement)) {
throw new Error('video element required before load()');
}
player.attachMediaElement(videoEl);
player.load();
} Type guard
function isAttached(player) {
return player._mediaElement instanceof HTMLMediaElement;
} Try / catch
try {
player.load();
} catch (e) {
if (/must be attached before load/.test(e.message)) {
player.attachMediaElement(videoEl);
player.load();
} else throw e;
} Prevention
- Adopt a fixed init order: createPlayer -> attachMediaElement -> load.
- Wrap async init so load() only runs after the <video> element is resolved.
- Assert the media element exists in DOM before initializing playback.
When it happens
Trigger: Calling player.load() (directly or via attachMediaElement's flow) when this._mediaElement is null — i.e. creating the player with flvjs.createPlayer() but never calling player.attachMediaElement(videoEl) — at src/player/flv-player.js:189.
Common situations: Headless/background initialization that defers DOM attachment, attaching the video element after an async step but calling load() before it resolves, or forgetting attachMediaElement entirely.
Related errors
- FlvPlayer.load() has been called, please call unload() first
- HTMLMediaElement must be attached before load()!
- MediaSource has been attached to an HTMLMediaElement!
- Url must be a non-empty string!
- FlvPlayer requires an flv MediaDataSource input!
AI-assisted analysis of bilibili/flv.js@42343088f2 (2026-09-01).
Data as JSON: /api/errors/9b18d3b741a11ae8.
Report an issue: GitHub.