{"record":{"id":"913c68ff41860359","repo":"louislam/uptime-kuma","slug":"multiple-columns-were-found-expected-only-one-val-913c68","errorCode":null,"errorMessage":"Multiple columns were found, expected only one value","messagePattern":"Multiple columns were found, expected only one value","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/oracledb.js","lineNumber":138,"sourceCode":"                password: password,\n            });\n            const result = await connection.execute(query, [], {\n                outFormat: oracledb.OUT_FORMAT_OBJECT,\n            });\n\n            if (!result.rows || result.rows.length === 0) {\n                throw new Error(\"Query returned no results\");\n            }\n\n            if (result.rows.length > 1) {\n                throw new Error(\"Multiple values were found, expected only one value\");\n            }\n\n            const firstRow = result.rows[0];\n            const columnNames = Object.keys(firstRow);\n\n            if (columnNames.length > 1) {\n                throw new Error(\"Multiple columns were found, expected only one value\");\n            }\n\n            return firstRow[columnNames[0]];\n        } catch (error) {\n            log.debug(this.name, \"Error caught in the query execution.\", error.message);\n            throw error;\n        } finally {\n            if (connection) {\n                await connection.close();\n            }\n        }\n    }\n}\n\nmodule.exports = {\n    OracleDbMonitorType,\n};\n","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/oracledb.js#L120-L156","documentation":"The OracleDB monitor expects a SQL query that returns exactly one scalar value (one row, one column). After verifying rows.length === 1, it inspects the first row's keys; if Object.keys(firstRow).length > 1, the SELECT projected more than one column and there is no unambiguous value to report, so it aborts rather than guessing. This is a usage contract enforced by the monitor, not by the oracledb driver itself.","triggerScenarios":"A monitor's query string returns multiple columns, e.g. SELECT id, name FROM users or SELECT count(*), max(ts) FROM logs. Any query whose first row deserializes to an object with two or more own keys trips the guard at oracledb.js:138 before the return.","commonSituations":"Authoring a diagnostic query with extra columns for context, copy-pasting a row-returning query into a single-value monitor, or a query that conditionally adds columns. The earlier rows.length > 1 check ('Multiple values were found') handles multi-row cases; this one is specifically multi-column.","solutions":["Rewrite the monitor query to project exactly one column, e.g. SELECT count(*) FROM table.","Wrap multi-column logic in a scalar subquery, e.g. SELECT (SELECT count(*) FROM t) FROM dual.","Validate the query in SQL*Plus / SQL Developer first and confirm a single value cell is returned.","If you need multiple metrics, create one OracleDB monitor per metric rather than one multi-column query."],"exampleFix":"// before\nconst sql = \"SELECT id, name FROM users WHERE rownum = 1\";\n// after\nconst sql = \"SELECT count(*) FROM users\";","handlingStrategy":"validation","validationCode":"// Before running the OracleDB monitor, sanity-check the query shape by\n// executing it once with ROWNUM = 1 and asserting a single column.\nasync function validateOracleScalarQuery(pool, sql) {\n  const wrapped = `SELECT * FROM (${sql}) WHERE ROWNUM = 1`;\n  const r = await pool.execute(wrapped);\n  const row = r.rows && r.rows[0];\n  if (!row) throw new Error('Query returned no rows');\n  const cols = Object.keys(row);\n  if (cols.length !== 1) {\n    throw new Error(`Query must return exactly 1 column, got ${cols.length}: ${cols.join(', ')}`);\n  }\n}","typeGuard":"// Narrow a query result to a single scalar.\nfunction isScalarRow(row) {\n  return !!row && typeof row === 'object' && Object.keys(row).length === 1;\n}","tryCatchPattern":"// In a wrapper around the monitor query: distinguish multi-column from multi-row.\ntry {\n  await oracledbMonitor.check(monitor, heartbeat, server);\n} catch (e) {\n  if (/Multiple columns were found/.test(e.message)) {\n    log.error('Fix the monitor query to SELECT a single column');\n  }\n  throw e;\n}","preventionTips":["Standardize on aggregate functions (count, max, min) for single-value monitors.","Document the one-row/one-column contract next to the query input.","Add a CI test that runs each saved monitor query against a dev DB and asserts one column."],"tags":["oracledb","sql","query-validation","monitor"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}