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

  1. Pass a valid constructor: customSeekHandler: MySeekHandler (the class itself, not an instance)
  2. Implement the custom handler as a class/function compatible with SeekHandler (getConfig, resolveSeekRequest, etc.)
  3. Verify the config key spelling: customSeekHandler
  4. 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

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


AI-assisted analysis of bilibili/flv.js@42343088f2 (2026-09-01). Data as JSON: /api/errors/031a3d434ed4a0de. Report an issue: GitHub.