{"record":{"id":"8f823f8c3199b644","repo":"louislam/uptime-kuma","slug":"invalid-json-in-database-query-error-message","errorCode":null,"errorMessage":"Invalid JSON in database query: ${error.message}","messagePattern":"Invalid JSON in database query: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/model/monitor.js","lineNumber":1777,"sourceCode":"                const maxDelayFromTimeout = this.interval * 1000 * 0.8;\n                if (delay >= maxDelayFromTimeout) {\n                    throw new Error(`Screenshot delay must be less than ${maxDelayFromTimeout}ms (0.8 × interval)`);\n                }\n\n                // Must not exceed 0.5 * interval to prevent blocking next check\n                const maxDelayFromInterval = this.interval * 1000 * 0.5;\n                if (delay >= maxDelayFromInterval) {\n                    throw new Error(`Screenshot delay must be less than ${maxDelayFromInterval}ms (0.5 × interval)`);\n                }\n            }\n        }\n\n        if (this.type === \"mongodb\" && this.databaseQuery) {\n            // Validate that databaseQuery is valid JSON\n            try {\n                JSON.parse(this.databaseQuery);\n            } catch (error) {\n                throw new Error(`Invalid JSON in database query: ${error.message}`);\n            }\n        }\n    }\n\n    /**\n     * Gets monitor notification of multiple monitor\n     * @param {Array} monitorIDs IDs of monitor to get\n     * @returns {Promise<LooseObject<any>>} object\n     */\n    static async getMonitorNotification(monitorIDs) {\n        return await R.getAll(\n            `\n            SELECT monitor_notification.monitor_id, monitor_notification.notification_id\n            FROM monitor_notification\n            WHERE monitor_notification.monitor_id IN (${monitorIDs.map((_) => \"?\").join(\",\")})\n        `,\n            monitorIDs\n        );","sourceCodeStart":1759,"sourceCodeEnd":1795,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/model/monitor.js#L1759-L1795","documentation":"Thrown by Monitor.validate() for type \"mongodb\" when databaseQuery is set and JSON.parse fails. The query is stored as a JSON string and later parsed by the MongoDB monitor to build a find/aggregation call, so malformed JSON would crash at check time.","triggerScenarios":"Save a mongodb monitor with databaseQuery containing trailing commas, single quotes, unquoted keys, comments, or unescaped characters. e.g. \"{ limit: 1, }\" or \"{'field': 1}\".","commonSituations":"User pastes a Mongo shell expression (JS object literal) instead of strict JSON. Editing the query in a text editor that auto-inserts smart quotes. Copying from MongoDB Compass which may emit shell syntax.","solutions":["Write strict JSON: double-quoted keys, no trailing commas, no comments, e.g. \"{ \"limit\": 1, \"sort\": { \"_id\": -1 } }\".","Validate the string with a JSON linter or JSON.parse before submitting.","If you need shell-only syntax, convert it to JSON first using a tool such as `mongo --eval` to canonicalize."],"exampleFix":"// before\n{ type: \"mongodb\", databaseQuery: \"{ limit: 1, }\" }\n// after\n{ type: \"mongodb\", databaseQuery: \"{ \\\"limit\\\": 1 }\" }","handlingStrategy":"validation","validationCode":"function validMongoQuery(q) {\n  if (!q) return true;\n  try { JSON.parse(q); return true; } catch { return false; }\n}","typeGuard":"function isJsonString(v) {\n  if (typeof v !== \"string\" || v.length === 0) return v == null;\n  try { JSON.parse(v); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await bean.validate();\n} catch (e) {\n  if (/Invalid JSON in database query/.test(e.message)) return badRequest(\"databaseQuery must be strict JSON\");\n  throw e;\n}","preventionTips":["Run the query through JSON.parse in a scratch pad before saving.","Prefer building the query with JSON.stringify(obj) so quoting is automatic."],"tags":["monitor","mongodb","validation","json","uptime-kuma"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}