{"record":{"id":"7f01982c6b320800","repo":"louislam/uptime-kuma","slug":"remote-browser-not-found","errorCode":null,"errorMessage":"Remote browser not found","messagePattern":"Remote browser not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/remote-browser.js","lineNumber":14,"sourceCode":"const { R } = require(\"redbean-node\");\n\nclass RemoteBrowser {\n    /**\n     * Gets remote browser from ID\n     * @param {number} remoteBrowserID ID of the remote browser\n     * @param {number} userID ID of the user who created the remote browser\n     * @returns {Promise<Bean>} Remote Browser\n     */\n    static async get(remoteBrowserID, userID) {\n        let bean = await R.findOne(\"remote_browser\", \" id = ? AND user_id = ? \", [remoteBrowserID, userID]);\n\n        if (!bean) {\n            throw new Error(\"Remote browser not found\");\n        }\n\n        return bean;\n    }\n\n    /**\n     * Save a Remote Browser\n     * @param {object} remoteBrowser Remote Browser to save\n     * @param {?number} remoteBrowserID ID of the Remote Browser to update\n     * @param {number} userID ID of the user who adds the Remote Browser\n     * @returns {Promise<Bean>} Updated Remote Browser\n     */\n    static async save(remoteBrowser, remoteBrowserID, userID) {\n        let bean;\n\n        if (remoteBrowserID) {\n            bean = await R.findOne(\"remote_browser\", \" id = ? AND user_id = ? \", [remoteBrowserID, userID]);\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/remote-browser.js#L1-L32","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet rb = await RemoteBrowser.get(id, userID); // throws on miss\n\n// after\nlet rb;\ntry {\n    rb = await RemoteBrowser.get(id, userID);\n} catch (e) {\n    throw new ErrorNotFound(\"Remote browser not found\");\n}","handlingStrategy":"try-catch","validationCode":"// Verify ownership/existence before calling get()\nconst exists = await R.findOne('remote_browser', ' id = ? AND user_id = ? ', [Number(id), userID]);\nif (!exists) return { ok: false, msg: 'Remote browser not found' };","typeGuard":"// Ensure the ID is a valid integer belonging to the user before lookup\nfunction isValidRemoteBrowserId(id, userID) {\n  return Number.isInteger(Number(id)) && Number.isInteger(userID);\n}","tryCatchPattern":"try {\n  const rb = await RemoteBrowser.get(remoteBrowserID, userID);\n} catch (e) {\n  if (/Remote browser not found/.test(e.message)) return notFound();\n  throw e;\n}","preventionTips":["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."],"tags":["crud","not-found","redbean","ownership","remote-browser"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}