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
- Only pass senders obtained directly from pc.getSenders() or the ontrack event's event.sender of the same pc.
- Validate before calling: if (sender && pc.getSenders().includes(sender)) pc.removeTrack(sender).
- Fix code that passes event.track or a sender id instead of the RTCRtpSender object.
- 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
- Pass only senders from pc.getSenders() or ontrack's event.sender.
- Never pass event.track where a sender is required.
- Do not serialize/clone sender objects across state boundaries.
- Look up the sender at call time instead of caching loose references.
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)