iflytek/astron-agent · error · DOMException

NotSupportedError

NotSupportedError

Error message

The adapter.js addTrack polyfill only supports a single  stream which is associated with the specified track.

What it means

The adapter.js addTrack polyfill predates multi-stream track association: it requires exactly one stream argument (r.length === 1) and that the given track actually belongs to that stream (r[0].getTracks().find(e => e === t)). If addTrack is called with zero arguments, multiple streams, or a stream that does not contain the track, it throws DOMException(..., 'NotSupportedError') because the polyfill cannot represent that case.

Solutions

  1. Always pass exactly one MediaStream that actually contains the track: pc.addTrack(track, streamContainingTrack).
  2. Upgrade the browser or the avatar SDK/adapter.js bundle so the native addTrack (no polyfill) is used.
  3. If the track is not in the stream, add it first (stream.addTrack(track)) before calling addTrack, or pass the stream the track actually came from.
  4. Avoid cloning/re-wrapping tracks between streams before publishing.

Example fix

// before
pc.addTrack(audioTrack); // no stream -> NotSupportedError in polyfill
// after
const outStream = new MediaStream([audioTrack]);
pc.addTrack(audioTrack, outStream);
Defensive patterns

Strategy: validation

Validate before calling

function canAddTrack(pc, track, stream) {
  return stream && stream.getTracks().includes(track) && pc.signalingState !== 'closed';
}

Try / catch

try { pc.addTrack(track, stream); } catch (e) {
  if (e.name === 'NotSupportedError' && /addTrack polyfill/.test(e.message)) {
    stream.addTrack(track);
    pc.addTrack(track, stream);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling pc.addTrack(track) with no stream; pc.addTrack(track, streamA, streamB) with more than one stream; or pc.addTrack(track, streamB) where track came from a different MediaStream (common when tracks are re-wrapped, cloned, or re-muxed by the SDK).

Common situations: Modern code written against the spec's optional stream argument running on an old browser where adapter.js polyfills addTrack; passing a newly constructed MediaStream that only wraps the track by reference in a different browser context; SDK versions that hand the player re-wrapped streams.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/841523c4a72002ae. Report an issue: GitHub.

Appendix: source

Thrown at console/frontend/src/utils/avatar-sdk-web_3.1.2.1002/xrtc-player-BJTnVhG9.js:19408

  }
  ((e.RTCPeerConnection.prototype.removeStream = function (e) {
    ((this._streams = this._streams || {}),
      (this._reverseStreams = this._reverseStreams || {}),
      n.apply(this, [this._streams[e.id] || e]),
      delete this._reverseStreams[
        this._streams[e.id] ? this._streams[e.id].id : e.id
      ],
      delete this._streams[e.id]);
  }),
    (e.RTCPeerConnection.prototype.addTrack = function (t, i) {
      if ('closed' === this.signalingState)
        throw new DOMException(
          "The RTCPeerConnection's signalingState is 'closed'.",
          'InvalidStateError'
        );
      const r = [].slice.call(arguments, 1);
      if (1 !== r.length || !r[0].getTracks().find(e => e === t))
        throw new DOMException(
          'The adapter.js addTrack polyfill only supports a single  stream which is associated with the specified track.',
          'NotSupportedError'
        );
      const n = this.getSenders().find(e => e.track === t);
      if (n)
        throw new DOMException('Track already exists.', 'InvalidAccessError');
      ((this._streams = this._streams || {}),
        (this._reverseStreams = this._reverseStreams || {}));
      const o = this._streams[i.id];
      if (o)
        (o.addTrack(t),
          Promise.resolve().then(() => {
            this.dispatchEvent(new Event('negotiationneeded'));
          }));
      else {
        const r = new e.MediaStream([t]);
        ((this._streams[i.id] = r),
          (this._reverseStreams[r.id] = i),

View on GitHub (pinned to 5e758547a8)