louislam/uptime-kuma · error · Error
Multiple columns were found, expected only one value
Error message
Multiple columns were found, expected only one value
What it means
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.
Source
Thrown at server/monitor-types/oracledb.js:138
password: password,
});
const result = await connection.execute(query, [], {
outFormat: oracledb.OUT_FORMAT_OBJECT,
});
if (!result.rows || result.rows.length === 0) {
throw new Error("Query returned no results");
}
if (result.rows.length > 1) {
throw new Error("Multiple values were found, expected only one value");
}
const firstRow = result.rows[0];
const columnNames = Object.keys(firstRow);
if (columnNames.length > 1) {
throw new Error("Multiple columns were found, expected only one value");
}
return firstRow[columnNames[0]];
} catch (error) {
log.debug(this.name, "Error caught in the query execution.", error.message);
throw error;
} finally {
if (connection) {
await connection.close();
}
}
}
}
module.exports = {
OracleDbMonitorType,
};
View on GitHub (pinned to 6b5ea01557)
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.
Example fix
// before const sql = "SELECT id, name FROM users WHERE rownum = 1"; // after const sql = "SELECT count(*) FROM users";
Defensive patterns
Strategy: validation
Validate before calling
// Before running the OracleDB monitor, sanity-check the query shape by
// executing it once with ROWNUM = 1 and asserting a single column.
async function validateOracleScalarQuery(pool, sql) {
const wrapped = `SELECT * FROM (${sql}) WHERE ROWNUM = 1`;
const r = await pool.execute(wrapped);
const row = r.rows && r.rows[0];
if (!row) throw new Error('Query returned no rows');
const cols = Object.keys(row);
if (cols.length !== 1) {
throw new Error(`Query must return exactly 1 column, got ${cols.length}: ${cols.join(', ')}`);
}
} Type guard
// Narrow a query result to a single scalar.
function isScalarRow(row) {
return !!row && typeof row === 'object' && Object.keys(row).length === 1;
} Try / catch
// In a wrapper around the monitor query: distinguish multi-column from multi-row.
try {
await oracledbMonitor.check(monitor, heartbeat, server);
} catch (e) {
if (/Multiple columns were found/.test(e.message)) {
log.error('Fix the monitor query to SELECT a single column');
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Query returned no results
- Multiple values were found, expected only one value
- domain_expiry_unsupported_monitor_type
- domain_expiry_unsupported_missing_target
- The oauth config is invalid. ${e.message}
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/913c68ff41860359.
Report an issue: GitHub.