{"record":{"id":"48aee3721df9b51e","repo":"louislam/uptime-kuma","slug":"proxy-not-found","errorCode":null,"errorMessage":"proxy not found","messagePattern":"proxy not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/proxy.js","lineNumber":27,"sourceCode":"\nclass Proxy {\n    static SUPPORTED_PROXY_PROTOCOLS = [\"http\", \"https\", \"socks\", \"socks5\", \"socks5h\", \"socks4\"];\n\n    /**\n     * Saves and updates given proxy entity\n     * @param {object} proxy Proxy to store\n     * @param {number} proxyID ID of proxy to update\n     * @param {number} userID ID of user the proxy belongs to\n     * @returns {Promise<Bean>} Updated proxy\n     */\n    static async save(proxy, proxyID, userID) {\n        let bean;\n\n        if (proxyID) {\n            bean = await R.findOne(\"proxy\", \" id = ? AND user_id = ? \", [proxyID, userID]);\n\n            if (!bean) {\n                throw new Error(\"proxy not found\");\n            }\n        } else {\n            bean = R.dispense(\"proxy\");\n        }\n\n        // Make sure given proxy protocol is supported\n        if (!this.SUPPORTED_PROXY_PROTOCOLS.includes(proxy.protocol)) {\n            throw new Error(`\n                Unsupported proxy protocol \"${proxy.protocol}.\n                Supported protocols are ${this.SUPPORTED_PROXY_PROTOCOLS.join(\", \")}.\"`);\n        }\n\n        // When proxy is default update deactivate old default proxy\n        if (proxy.default) {\n            await R.exec(\"UPDATE proxy SET `default` = 0 WHERE `default` = 1\");\n        }\n\n        bean.user_id = userID;","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/proxy.js#L9-L45","documentation":"Thrown by Proxy.save during an update (proxyID provided) when no proxy row matches both proxyID and userID. Ownership is enforced via the AND user_id predicate, mirroring Notification.save; a miss means the proxy does not exist or belongs to another user.","triggerScenarios":"Updating a proxy that was already deleted, stale proxyID in the client, user_id mismatch from a tampered request, or concurrent deletion.","commonSituations":"Browser holds a proxyID after the row was removed elsewhere, multi-user instance where one user tries to edit another's proxy, or replayed form submission.","solutions":["Reload the proxy list in the UI to get fresh ids and retry.","Verify the proxy row's user_id matches the logged-in user in the DB.","If the proxy was deleted, create a new one instead of editing the stale id.","Check server logs for the exact (proxyID, userID) pair passed to Proxy.save."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify ownership before updating a proxy\nasync function proxyExistsForUser(proxyID, userID) {\n    const bean = await R.findOne(\"proxy\", \" id = ? AND user_id = ? \", [proxyID, userID]);\n    return bean != null;\n}\nif (proxyID && !(await proxyExistsForUser(proxyID, userID))) {\n    throw new Error(\"proxy not found\");\n}","typeGuard":"/** True when a proxy bean was found for the (id, user) pair. */\nfunction isOwnedProxy(bean) { return bean != null; }","tryCatchPattern":"try {\n    const bean = await R.findOne(\"proxy\", \" id = ? AND user_id = ? \", [proxyID, userID]);\n    if (!bean) throw new Error(\"proxy not found\");\n    // ...proceed with update\n} catch (err) { throw err; }","preventionTips":["Refresh the proxy list before editing.","Confirm the logged-in user owns the proxy.","Avoid concurrent edits across sessions."],"tags":["proxy","ownership","not-found","crud"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}