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

  1. Confirm the remoteBrowserID still exists for the current user before calling get() (e.g. list the user's remote browsers and match).
  2. Verify the ID is an integer and belongs to the requesting user via an ownership check earlier in the request flow.
  3. Catch the error in the handler and return a 404/not-found to the client instead of letting it surface as a 500.
  4. 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

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


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/7f01982c6b320800. Report an issue: GitHub.