{"record":{"id":"3fdc0b35dd9460bb","repo":"risingwavelabs/risingwave","slug":"bad-result-from-sqlite","errorCode":null,"errorMessage":"bad result from sqlite","messagePattern":"bad result from sqlite","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/rpc/election/sql.rs","lineNumber":191,"sourceCode":"                END,\n                last_heartbeat = CASE\n                                     WHEN DATETIME({table}.last_heartbeat, '+' || $3 || ' seconds') < CURRENT_TIMESTAMP THEN EXCLUDED.last_heartbeat\n                                     WHEN {table}.id = EXCLUDED.id THEN EXCLUDED.last_heartbeat\n                                     ELSE {table}.last_heartbeat\n                    END\n        RETURNING service, id, last_heartbeat;\n        \"#,\n                    table = Self::election_table_name()\n                ),\n                vec![Value::from(service_name), Value::from(id), Value::from(ttl)],\n            ))\n            .await?;\n\n        let row = query_result\n            .map(|query_result| ElectionRow::from_query_result(&query_result, \"\"))\n            .transpose()?;\n\n        let row = row.ok_or_else(|| anyhow!(\"bad result from sqlite\"))?;\n\n        Ok(row)\n    }\n\n    async fn leader(&self, service_name: &str) -> MetaResult<Option<ElectionRow>> {\n        let query_result = self\n            .conn\n            .query_one(Statement::from_sql_and_values(\n                DatabaseBackend::Sqlite,\n                format!(\n                    r#\"SELECT service, id, last_heartbeat FROM {table} WHERE service = $1;\"#,\n                    table = Self::election_table_name()\n                ),\n                vec![Value::from(service_name)],\n            ))\n            .await?;\n\n        let row = query_result","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/rpc/election/sql.rs#L173-L209","documentation":"The SQLite-backed meta election implementation runs an INSERT ... ON CONFLICT style campaign query and expects exactly one row back identifying the leader. When the query succeeds but returns no row, try_campaign rejects with 'bad result from sqlite'. This indicates the election query's contract (a guaranteed row) was violated by the store.","triggerScenarios":"try_campaign on SqliteElectionClient when the campaign upsert query returns an empty result set, i.e. the row inserted/updated cannot be read back.","commonSituations":"Corrupted or concurrently wiped sqlite meta store file; running multiple meta nodes against a sqlite store not intended for HA; sqlite driver/behavior changes returning no rows for the upsert.","solutions":["Verify the sqlite meta store file is intact and not shared by multiple meta processes; use a single meta node with sqlite.","Check meta logs for preceding sqlite errors (lock, corruption) and restore the meta store from backup if corrupted.","Restart the meta node to re-run election and repopulate the row.","If reproducible, file a bug: the campaign query should always return a row, so this signals a driver or query defect."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// detect the empty election row and retry campaign with backoff\nmatch client.try_campaign(service, lock_id).await {\n    Err(e) if e.to_string().contains(\"bad result from sqlite\") => {\n        tokio::time::sleep(Duration::from_secs(1)).await;\n        // verify store integrity before retrying\n    }\n    other => other?,\n}","preventionTips":["Use sqlite only for single-node meta deployments.","Monitor meta store file integrity and disk health.","Pin and test the sqlx/driver version against your sqlite version."],"tags":["sqlite","election","meta","leader-election"],"backgroundTag":"empty-result-set","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}