iflytek/astron-agent · error · DOMException

TypeError

TypeError

Error message

Argument 1 of RTCPeerConnection.removeTrack does not implement interface RTCRtpSender.

What it means

Thrown by the adapter.js removeTrack polyfill when the argument passed to RTCPeerConnection.removeTrack is not a real RTCRtpSender — the polyfill detects this via the internal _pc marker property that native senders (or polyfilled senders) carry. A plain object, an undefined value, or a sender produced by a different/connection-incompatible implementation lacks _pc and triggers this TypeError.

Solutions

  1. Only pass senders obtained directly from pc.getSenders() or the ontrack event's event.sender of the same pc.
  2. Validate before calling: if (sender && pc.getSenders().includes(sender)) pc.removeTrack(sender).
  3. Fix code that passes event.track or a sender id instead of the RTCRtpSender object.
  4. Do not serialize/clone senders across boundaries; keep live references.

Example fix

// before
pc.removeTrack(evt.track); // wrong object

// after
const sender = pc.getSenders().find(s => s.track === evt.track);
if (sender) pc.removeTrack(sender);
Defensive patterns

Strategy: type-guard

Validate before calling

function isValidSender(pc, sender) {
  return !!sender && typeof sender.track !== 'undefined' && pc.getSenders().includes(sender);
}

Type guard

function isSender(pc, s) {
  return !!s && '_pc' in s && pc.getSenders().includes(s);
}

Try / catch

try {
  pc.removeTrack(sender);
} catch (e) {
  if (e instanceof TypeError) {
    // argument was not an RTCRtpSender; resolve correct sender via getSenders()
  } else throw e;
}

Prevention

When it happens

Trigger: Passing null/undefined to pc.removeTrack(), passing a mock or a deserialized sender object, or passing a sender obtained from a different peer connection or from a different adapter version than the one installed on this pc.

Common situations: Storing senders in state (e.g. React state or JSON) that loses the internal fields, refactoring that passes an event.track instead of event.sender, or mixing the bundled XRTC adapter with a natively created connection.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

  };
  const a = Object.getOwnPropertyDescriptor(
    e.RTCPeerConnection.prototype,
    'localDescription'
  );
  (Object.defineProperty(e.RTCPeerConnection.prototype, 'localDescription', {
    get() {
      const e = a.get.apply(this);
      return '' === e.type ? e : o(this, e);
    },
  }),
    (e.RTCPeerConnection.prototype.removeTrack = function (e) {
      if ('closed' === this.signalingState)
        throw new DOMException(
          "The RTCPeerConnection's signalingState is 'closed'.",
          'InvalidStateError'
        );
      if (!e._pc)
        throw new DOMException(
          'Argument 1 of RTCPeerConnection.removeTrack does not implement interface RTCRtpSender.',
          'TypeError'
        );
      if (e._pc !== this)
        throw new DOMException(
          'Sender was not created by this connection.',
          'InvalidAccessError'
        );
      let t;
      ((this._streams = this._streams || {}),
        Object.keys(this._streams).forEach(i => {
          this._streams[i].getTracks().find(t => e.track === t) &&
            (t = this._streams[i]);
        }),
        t &&
          (1 === t.getTracks().length
            ? this.removeStream(this._reverseStreams[t.id])
            : t.removeTrack(e.track),

View on GitHub (pinned to 5e758547a8)