NativeScript/NativeScript · error · Error
Failed to execute 'send' on 'XMLHttpRequest': The object's s
Error message
Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.
What it means
XMLHttpRequest.send() in @nativescript/core requires the request to be in the OPENED state (after a successful open() call) and not already sent. The implementation checks this.readyState !== OPENED || this._sendFlag and throws to mirror the browser spec, where send() on an uns opened or already-sent request is an InvalidStateError. It enforces the one-request-per-XHR lifecycle.
Source
Thrown at packages/core/xhr/index.ts:233
this._errorFlag = true;
this._sendFlag = false;
this._setRequestError('abort');
}
if (this._readyState === this.DONE) {
this._readyState = this.UNSENT;
}
}
public send(data?: any) {
this._errorFlag = false;
this._response = null;
this._responseTextReader = null;
this._headers = null;
this._status = null;
if (this._readyState !== this.OPENED || this._sendFlag) {
throw new Error("Failed to execute 'send' on 'XMLHttpRequest': " + "The object's state must be OPENED.");
}
if (isString(data) && this._options.method !== 'GET') {
//The Android Java HTTP lib throws an exception if we provide a
//a request body for GET requests, so we avoid doing that.
//Browser implementations silently ignore it as well.
this._options.content = data;
} else if (data instanceof FormData) {
this._options.content = (<FormData>data).toString();
} else if (data instanceof Blob) {
this.setRequestHeader('Content-Type', data.type);
this._options.content = Blob.InternalAccessor.getBuffer(data);
} else if (data instanceof ArrayBuffer) {
this._options.content = data;
}
this._sendFlag = true;
View on GitHub (pinned to 6800aefa65)
Solutions
- Call xhr.open(method, url) before calling send().
- Create a fresh XMLHttpRequest instance for each request instead of reusing one.
- Guard with a state check: only send when xhr.readyState === xhr.OPENED and not already sent.
- If retrying, wrap the open+send sequence in a function that builds a new XHR each time.
Example fix
// before
const xhr = new XMLHttpRequest();
xhr.send(null); // throws
// after
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send(null); Defensive patterns
Strategy: validation
Validate before calling
if (xhr.readyState === xhr.OPENED && !xhr._sendFlag) { xhr.send(data); } Type guard
function canSend(xhr) { return xhr.readyState === xhr.OPENED; } Try / catch
try { xhr.send(data); } catch (e) { if (String(e.message).includes("state must be OPENED")) { /* create new XHR, open, send */ } else { throw e; } } Prevention
- Always pair open() immediately before send().
- Never reuse an XHR object for a second request.
- Centralize XHR creation in one helper so open+send ordering is guaranteed.
- Don't call send() from response handlers.
When it happens
Trigger: Calling xhr.send() before calling xhr.open(); calling send() twice on the same XMLHttpRequest instance (the second call hits _sendFlag === true); calling send() after abort() or after the request reached DONE without resetting via open().
Common situations: Event-handler race where an async callback retries send() on the same object; copy-pasted code that forgets open(); wrapping send in retry logic without creating a new XHR instance; calling send from onreadystatechange handlers after completion.
Related errors
- Failed to execute 'setRequestHeader' on 'XMLHttpRequest': Th
- Failed to execute 'overrideMimeType' on 'XMLHttpRequest': Mi
- Response type of '${value}' not supported.
- Failed to read the 'responseText' property from 'XMLHttpRequ
AI-assisted analysis of NativeScript/NativeScript@6800aefa65 (2026-08-30).
Data as JSON: /api/errors/094174541225a431.
Report an issue: GitHub.