{"record":{"id":"f6d9b81a041d9730","repo":"neondatabase/neon","slug":"expected-1-query-results-but-got","errorCode":null,"errorMessage":"expected 1 query results, but got {}","messagePattern":"expected 1 query results, but got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compute_tools/src/checker.rs","lineNumber":34,"sourceCode":"    }\n\n    // The connection object performs the actual communication with the database,\n    // so spawn it off to run on its own.\n    tokio::spawn(async move {\n        if let Err(e) = connection.await {\n            error!(\"connection error: {}\", e);\n        }\n    });\n\n    let query = \"\n    INSERT INTO public.health_check VALUES (1, pg_catalog.now())\n        ON CONFLICT (id) DO UPDATE\n         SET updated_at = pg_catalog.now();\";\n\n    match client.simple_query(query).await {\n        Result::Ok(result) => {\n            if result.len() != 1 {\n                return Err(anyhow::anyhow!(\n                    \"expected 1 query results, but got {}\",\n                    result.len()\n                ));\n            }\n        }\n        Err(err) => {\n            if let Some(state) = err.code() {\n                if state == &tokio_postgres::error::SqlState::DISK_FULL {\n                    warn!(\"Tenant disk is full\");\n                    return Ok(());\n                }\n            }\n            return Err(err.into());\n        }\n    }\n\n    Ok(())\n}","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/compute_tools/src/checker.rs#L16-L52","documentation":"The availability checker runs a single INSERT ... ON CONFLICT DO UPDATE via simple_query and asserts that exactly one result set comes back. PostgreSQL/tokio-postgres returned zero or more than one result, so the invariant 'one statement, one result' was violated and the check fails. It is an internal sanity check on the driver/protocol behavior rather than a database fault.","triggerScenarios":"client.simple_query(\"INSERT INTO public.health_check VALUES (1, now()) ON CONFLICT (id) DO UPDATE SET updated_at = now()\") returns a Vec whose len() != 1: an empty response (degraded connection, mid-protocol failure) or multiple responses (query string grew to several statements, driver behavior change across tokio-postgres versions).","commonSituations":"tokio-postgres upgraded to a version that batches/splits simple query results differently; someone edits the query into a multi-statement string; a proxy (pgbouncer in statement mode) splitting or rewriting the statement; flaky connection returning an empty result set.","solutions":["Log and inspect result.len() and the returned command tags to see which side of 1 you got","Confirm the query string is still exactly one statement (no semicolons appended)","Pin/check the tokio-postgres version in Cargo.lock against the one this invariant was written for","If driver behavior legitimately changed, relax the check to len() >= 1 or check that at least one entry is a result row"],"exampleFix":"// before\nif result.len() != 1 {\n    return Err(anyhow!(\"expected 1 query results, but got {}\", result.len()));\n}\n// after\nif !result.iter().any(|r| matches!(r, SimpleQueryMessage::CommandComplete(_))) {\n    return Err(anyhow!(\"health_check INSERT produced no completed command, got {} messages\", result.len()));\n}","handlingStrategy":"validation","validationCode":"// Assert single-statement, single-result shape before trusting the check\nstatic EXPECTED_STMTS: usize = 1;\nif query.matches(';').count() > EXPECTED_STMTS { anyhow::bail!(\"checker query must stay a single statement\"); }","typeGuard":null,"tryCatchPattern":"match client.simple_query(query).await {\n    Ok(results) if results.len() == 1 => Ok(()),\n    Ok(results) => { warn!(\"unexpected {} results\", results.len()); Ok(()) } // degrade to warning, do not fail availability\n    Err(err) => { /* existing SqlState::DISK_FULL special case, else propagate */ }\n}","preventionTips":["Add a unit/integration test running the exact checker query against the pinned tokio-postgres version","Pin tokio-postgres in Cargo.lock and re-run checker tests on any bump","Keep the health-check statement as one statement; reject edits that append statements"],"tags":["rust","postgres","simple-query","health-check","invariant","tokio-postgres"],"backgroundTag":"unexpected-query-result","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}