louislam/uptime-kuma · error · Error
Remote browser not found
Error message
Remote browser not found
What it means
Thrown by RemoteBrowser.get() when a `remote_browser` row cannot be found matching BOTH the given `remoteBrowserID` and `userID`. The query is scoped by `id = ? AND user_id = ?`, so a miss means either the ID does not exist or it belongs to a different user. This is a standard RedBean lookup that treats a missing row as a hard failure rather than returning null.
Source
Thrown at server/remote-browser.js:14
const { R } = require("redbean-node");
class RemoteBrowser {
/**
* Gets remote browser from ID
* @param {number} remoteBrowserID ID of the remote browser
* @param {number} userID ID of the user who created the remote browser
* @returns {Promise<Bean>} Remote Browser
*/
static async get(remoteBrowserID, userID) {
let bean = await R.findOne("remote_browser", " id = ? AND user_id = ? ", [remoteBrowserID, userID]);
if (!bean) {
throw new Error("Remote browser not found");
}
return bean;
}
/**
* Save a Remote Browser
* @param {object} remoteBrowser Remote Browser to save
* @param {?number} remoteBrowserID ID of the Remote Browser to update
* @param {number} userID ID of the user who adds the Remote Browser
* @returns {Promise<Bean>} Updated Remote Browser
*/
static async save(remoteBrowser, remoteBrowserID, userID) {
let bean;
if (remoteBrowserID) {
bean = await R.findOne("remote_browser", " id = ? AND user_id = ? ", [remoteBrowserID, userID]);
View on GitHub (pinned to 6b5ea01557)
Solutions
- Confirm the remoteBrowserID still exists for the current user before calling get() (e.g. list the user's remote browsers and match).
- Verify the ID is an integer and belongs to the requesting user via an ownership check earlier in the request flow.
- Catch the error in the handler and return a 404/not-found to the client instead of letting it surface as a 500.
- Refresh the client's cached remote-browser list when this error is received so a stale ID is not retried.
Example fix
// before
let rb = await RemoteBrowser.get(id, userID); // throws on miss
// after
let rb;
try {
rb = await RemoteBrowser.get(id, userID);
} catch (e) {
throw new ErrorNotFound("Remote browser not found");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify ownership/existence before calling get()
const exists = await R.findOne('remote_browser', ' id = ? AND user_id = ? ', [Number(id), userID]);
if (!exists) return { ok: false, msg: 'Remote browser not found' }; Type guard
// Ensure the ID is a valid integer belonging to the user before lookup
function isValidRemoteBrowserId(id, userID) {
return Number.isInteger(Number(id)) && Number.isInteger(userID);
} Try / catch
try {
const rb = await RemoteBrowser.get(remoteBrowserID, userID);
} catch (e) {
if (/Remote browser not found/.test(e.message)) return notFound();
throw e;
} Prevention
- Scope all remote-browser lookups by user_id on the server.
- Coerce client-supplied IDs to integers before querying.
- Refresh the client list after delete so stale IDs are not reused.
- Return a clean 404 from handlers instead of letting the raw Error propagate.
When it happens
Trigger: Calling a socket/API handler that resolves a remote browser from a client-supplied ID, where the ID was never created, was deleted, or belongs to another account. Any caller of RemoteBrowser.get(remoteBrowserID, userID) passing an unverified ID triggers it.
Common situations: Stale ID cached in the frontend after the browser entry was deleted; cross-user access attempt; race where the row is trashed between the list loading and the detail/edit action; an off-by-one or string/number coercion in the ID passed from the client.
Related errors
- Remote Browser not found
- notification not found
- proxy not found
- docker host not found
- Monitor not found or not active.
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/7f01982c6b320800.
Report an issue: GitHub.