bilibili/flv.js · error · InvalidArgumentException
Custom seekType specified in config but invalid customSeekHa
Error message
Custom seekType specified in config but invalid customSeekHandler!
What it means
IOController._selectSeekHandler validates config.seekType; when seekType === 'custom' it requires config.customSeekHandler to be a constructor function. This InvalidArgumentException is thrown when seekType is 'custom' but customSeekHandler is missing, not a function (e.g. an object or undefined), or would fail to construct.
Source
Thrown at src/io/io-controller.js:231
}
get loaderType() {
return this._loader.type;
}
_selectSeekHandler() {
let config = this._config;
if (config.seekType === 'range') {
this._seekHandler = new RangeSeekHandler(this._config.rangeLoadZeroStart);
} else if (config.seekType === 'param') {
let paramStart = config.seekParamStart || 'bstart';
let paramEnd = config.seekParamEnd || 'bend';
this._seekHandler = new ParamSeekHandler(paramStart, paramEnd);
} else if (config.seekType === 'custom') {
if (typeof config.customSeekHandler !== 'function') {
throw new InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');
}
this._seekHandler = new config.customSeekHandler();
} else {
throw new InvalidArgumentException(`Invalid seekType in config: ${config.seekType}`);
}
}
_selectLoader() {
if (this._config.customLoader != null) {
this._loaderClass = this._config.customLoader;
} else if (this._isWebSocketURL) {
this._loaderClass = WebSocketLoader;
} else if (FetchStreamLoader.isSupported()) {
this._loaderClass = FetchStreamLoader;
} else if (MozChunkedLoader.isSupported()) {
this._loaderClass = MozChunkedLoader;
} else if (RangeLoader.isSupported()) {
this._loaderClass = RangeLoader;View on GitHub (pinned to 42343088f2)
Solutions
- Pass a valid constructor: customSeekHandler: MySeekHandler (the class itself, not an instance)
- Implement the custom handler as a class/function compatible with SeekHandler (getConfig, resolveSeekRequest, etc.)
- Verify the config key spelling: customSeekHandler
- If you don't need custom seeking, set seekType to 'range' or 'param' instead
Example fix
// before
const controller = new IOController(fetchLoader, { seekType: 'custom', customSeekHandler: new MySeekHandler() }, extraData);
// after
const controller = new IOController(fetchLoader, { seekType: 'custom', customSeekHandler: MySeekHandler }, extraData); // pass the class, not an instance Defensive patterns
Strategy: validation
Validate before calling
if (config.seekType === 'custom' && typeof config.customSeekHandler !== 'function') {
throw new TypeError('customSeekHandler must be a constructor function');
} Type guard
const hasValidCustomSeekHandler = (c) => c.seekType !== 'custom' || typeof c.customSeekHandler === 'function';
Try / catch
try {
const controller = new IOController(loaderClass, config, extraData);
} catch (e) {
if (e instanceof InvalidArgumentException && /customSeekHandler/.test(e.message)) {
config.seekType = 'range';
}
} Prevention
- Pass the handler class itself, never an instance
- Keep the customSeekHandler config key spelled exactly (camelCase)
- Unit-test config objects that use seekType:'custom'
- Prefer built-in 'range'/'param' seek types unless custom behavior is required
When it happens
Trigger: Creating an IOController (directly or via player/feature config) with { seekType: 'custom' } while customSeekHandler is undefined, null, a plain object, or a non-constructor value such as an arrow-function-returning-object used incorrectly.
Common situations: Copy-pasting a config that sets seekType:'custom' without supplying the handler, passing a class from another module that tree-shaking removed, typos in the config key (customSeekhandler), or passing an instance instead of the class itself.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Invalid seekType in config: ${config.seekType}
- FlvPlayer requires an flv MediaDataSource input!
- NativePlayer does't support flv MediaDataSource input!
AI-assisted analysis of bilibili/flv.js@42343088f2 (2026-09-01).
Data as JSON: /api/errors/031a3d434ed4a0de.
Report an issue: GitHub.