PhantomJS’s “null is not an object” error usually means your code found no element for a selector, then tried to use that missing element. Check that the page loaded, verify the selector against the live DOM, and wait for the specific element if the page creates it asynchronously. Keep the lookup and null check inside page.evaluate(), and return plain data rather than a DOM node.
What “null is not an object” means
document.querySelector(selector) returns null when no element in the current document matches the selector. If code then reads a property or calls a method on that result, JavaScript raises a TypeError. For example, this can fail if the page has no element with the ID map when the callback runs:
var box = page.evaluate(function () {
return document.querySelector('#map').getBoundingClientRect();
});
The important clue is the expression named in the error: find the value immediately before the property access or method call. In this example, it is the result of querySelector('#map'). The null may also come from another lookup or value; the error does not, by itself, prove that the selector is wrong. It means the code dereferenced a value that was null.
Fix it in this order
-
Check whether the page opened successfully
Do not begin DOM work until the
page.open(url, callback)callback reportssuccess. PhantomJS supplies eithersuccessorfailafter the load attempt. A failed load is a different problem from a selector mismatch, so log the URL and stop before evaluating page code when status is not successful.Recommended Free Tools
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
-
Check for the element and handle absence
Run the lookup and its null check together inside
page.evaluate(). Return a small object containing simple values that the PhantomJS script can inspect:var result = page.evaluate(function (selector) { var element = document.querySelector(selector); if (!element) { return { found: false, readyState: document.readyState }; } return { found: true, text: element.textContent || '' }; }, '#map'); if (!result.found) { console.log('Element not found; check the selector or page readiness.'); } else { console.log(result.text); }This prevents a missing match from turning into a second, less informative failure. It also lets the calling script decide whether to wait, report a selector problem, or exit with an error.
-
Verify the selector character by character
Compare the selector with the markup in the document PhantomJS actually loaded. Check the tag, ID, class, attribute name and value, quotation marks, brackets, and spaces. A small syntax difference can make a valid-looking selector match nothing. For instance,
img [alt="PhantomJS"]contains a space betweenimgand the attribute selector; it means something different fromimg[alt="PhantomJS"]. The latter selects an image with that attribute, while the former looks for a matching descendant.Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Inspect
page.contentor render the page to see its markup, then correct the selector to match that markup. If the page uses a class or attribute that changes between visits, avoid assuming a value that is not stable.Free tools Windows power users keep installed
One-click scans. No signup required.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy. -
Wait for dynamic content
A successful
page.open()callback establishes that the page load completed successfully; it does not guarantee that every element added later by page JavaScript already exists. If the target appears after an asynchronous request, animation, or framework update, an immediate query can still return null. Use a readiness condition tied to the target or a meaningful page state instead of assuming that a successful load means the application is ready. -
Confirm the document and frame
Selectors run against the DOM for the page context being evaluated. If the target is in an iframe, querying the top-level document will not find it; select the appropriate frame before running the query. Also check whether the page navigated after the initial load. Log
page.urland inspect the current document before drawing conclusions from a selector that was expected on a different page.Rank #3
SaleAnker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
-
Record enough context to diagnose the next failure
For a failed lookup, capture the URL, load status, selector,
document.readyState, and a short excerpt ofpage.content. If you need messages emitted by page-side code, setpage.onConsoleMessage; messages from the page’s evaluated context are not displayed by default in the PhantomJS script. This makes it easier to distinguish a bad selector from an unexpected page, a load failure, or content that has not rendered yet.
Use a bounded readiness check instead of guessing
When content is asynchronous, a deterministic check is more reliable than inserting an arbitrary delay. The following example polls the page for a selector until it appears or a timeout expires. It checks the load status first, waits between checks, and exits with distinct status codes for a load failure and a missing element.
var page = require('webpage').create();
var system = require('system');
var url = system.args[1];
var selector = system.args[2] || '#map';
var attempts = 30;
var intervalMillis = 200;
var attempt = 0;
page.onConsoleMessage = function (msg) {
console.log('PAGE: ' + msg);
};
page.open(url, function (status) {
if (status !== 'success') {
console.log('Unable to load: ' + url);
phantom.exit(1);
return;
}
function checkForElement() {
var result = page.evaluate(function (selector) {
var node = document.querySelector(selector);
return {
found: !!node,
readyState: document.readyState,
text: node ? (node.textContent || '') : ''
};
}, selector);
if (result.found) {
console.log(result.text);
phantom.exit(0);
return;
}
attempt += 1;
if (attempt >= attempts) {
console.log('Selector not found: ' + selector);
console.log('URL: ' + page.url);
console.log('Ready state: ' + result.readyState);
console.log('Markup excerpt: ' + page.content.substring(0, 500));
phantom.exit(2);
return;
}
setTimeout(checkForElement, intervalMillis);
}
checkForElement();
});
Save the script as check.js, then run it with the URL and, optionally, a CSS selector:
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
phantomjs check.js https://example.com '#map'
The example makes at most 30 checks, 200 milliseconds apart. Those values are a starting configuration, not a guarantee that a particular page will render within six seconds. Choose a limit suitable for the page and workload, and report a timeout rather than treating a missing element as success. If you already know that a specific asynchronous operation has completed, use that completion event or state as the readiness condition instead of polling an unrelated signal.
Keep PhantomJS page code inside its sandbox
page.evaluate() runs in the page’s JavaScript context, not as ordinary code sharing the PhantomJS script’s variables. Pass values such as selectors as arguments, and return simple values such as strings, booleans, numbers, arrays, or JSON-serializable objects. Do not expect DOM nodes, closures, or page objects to cross the boundary. For example, return an element’s text or a boolean indicating whether it exists, not the element itself.
For work that needs to happen later in the page context, PhantomJS provides evaluateAsync(function, delayMillis, ...). It is useful for delayed, non-blocking page-context work, but it does not remove the need to define what “ready” means or to handle the case where the requested element never appears. For a condition that your outer script must act on, the bounded polling pattern above makes the result explicit.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Common causes and fixes
| Symptom | Likely cause | What to check or change |
|---|---|---|
| Every selector lookup fails | The page did not load successfully, the script is on an unexpected URL, or the markup differs from what the selector expects. | Check the page.open() status, log page.url, and inspect page.content before changing selectors. |
| One selector fails while nearby content is present | A typo, extra space, incorrect attribute, or other selector mismatch. | Compare the selector with the live markup, including punctuation and whitespace. |
| The lookup fails early but succeeds later | The element is rendered asynchronously after the load callback. | Wait for that element or an application-specific readiness condition, with a finite timeout. |
| The top-level query cannot find an embedded target | The target belongs to a frame rather than the current document. | Switch to the appropriate frame, then evaluate the selector there. |
| The error persists after navigation | The script is evaluating a different document from the one expected. | Log the current URL and inspect the current document at the moment of evaluation. |
| The error appears to come from a page script | Page-side code may be logging or throwing within its own context. | Use page.onConsoleMessage to forward page console messages, and separate page-side logs from errors in the PhantomJS script. |
Or skip the browser setup
If your actual goal is to obtain a screenshot rather than interact with the DOM in a PhantomJS script, ScreenshotNeo offers a one-request screenshot API. This does not repair a PhantomJS selector or return a DOM element; it is an alternative for screenshot capture.
For example, cURL can save a WebP screenshot:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for API details. Cookie banners are accepted as a visitor and removed, along with known newsletter popups and chat widgets, before capture; each of those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server provides screenshot and PDF tools for AI agents, and the free plan includes 1,000 shots a month without a card; paid plans start at $5 for 3,000 shots. To try it, sign up for free.
When to choose each fix
- Load failure: handle the unsuccessful
page.open()status before any DOM query. - Selector mismatch: inspect the loaded markup and correct the selector precisely.
- Late rendering: wait for the target or a relevant state with a finite limit.
- Frame or navigation issue: query the document that actually contains the target.
- Sandbox confusion: pass arguments into
page.evaluate()and return serializable values.
These cases need different remedies; adding delay to a selector typo, for example, will not make it match. Diagnose from the current URL, status, selector, readiness state, and markup, then change the part that the evidence points to.
Frequently Asked Questions
Does `querySelector()` throw when it finds no match?
No. It returns `null`; the TypeError happens when later code dereferences that null result.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Can I return a DOM element from `page.evaluate()`?
No. Return simple or JSON-serializable data, such as the element’s text, dimensions, or whether it was found.
Should I add a fixed sleep after every page load?
Not by default. A selector- or state-based readiness check is more informative and avoids waiting unnecessarily when the page is ready sooner.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

