{"record":{"id":"3c3f859e6b8d3634","repo":"neondatabase/neon","slug":"file-cache-size-query-returned-no-rows","errorCode":null,"errorMessage":"file cache size query returned no rows","messagePattern":"file cache size query returned no rows","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/vm_monitor/src/filecache.rs","lineNumber":239,"sourceCode":"                    .await\n                    .context(\"failed to execute query a second time\")\n            }\n        }\n    }\n\n    /// Get the current size of the file cache.\n    #[tracing::instrument(skip_all)]\n    pub async fn get_file_cache_size(&mut self) -> anyhow::Result<u64> {\n        self.query_with_retry(\n            // The file cache GUC variable is in MiB, but the conversion with\n            // pg_size_bytes means that the end result we get is in bytes.\n            \"SELECT pg_size_bytes(current_setting('neon.file_cache_size_limit'));\",\n            &[],\n        )\n        .await\n        .context(\"failed to query pg for file cache size\")?\n        .first()\n        .ok_or_else(|| anyhow!(\"file cache size query returned no rows\"))?\n        // pg_size_bytes returns a bigint which is the same as an i64.\n        .try_get::<_, i64>(0)\n        // Since the size of the table is not negative, the cast is sound.\n        .map(|bytes| bytes as u64)\n        .context(\"failed to extract file cache size from query result\")\n    }\n\n    /// Attempt to set the file cache size, returning the size it was actually\n    /// set to.\n    #[tracing::instrument(skip_all, fields(%num_bytes))]\n    pub async fn set_file_cache_size(&mut self, num_bytes: u64) -> anyhow::Result<u64> {\n        let max_bytes = self\n            // The file cache GUC variable is in MiB, but the conversion with pg_size_bytes\n            // means that the end result we get is in bytes.\n            .query_with_retry(\n                \"SELECT pg_size_bytes(current_setting('neon.max_file_cache_size'));\",\n                &[],\n            )","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/libs/vm_monitor/src/filecache.rs#L221-L257","documentation":"`FileCache::get_file_cache_size` runs `SELECT pg_size_bytes(current_setting('neon.file_cache_size_limit'))` via `query_with_retry` and expects exactly one row containing the current cache size in bytes. Postgres returns a row for this scalar SELECT even when the setting is empty, so a zero-row result means the query path itself is broken (severe connection anomaly or a misbehaving client), not a missing setting.","triggerScenarios":"Calling `get_file_cache_size()` when the underlying postgres connection returns zero rows for the scalar SELECT — a degraded pool connection, a test-mocked sqlx client that forgot to enqueue a row for this statement, or a proxy mangling result sets.","commonSituations":"Unit tests with mocked SQL clients missing row fixtures; flaky connectivity between vm-monitor and the compute node's postgres; running the monitor against a non-Neon postgres or through a misconfigured pgbouncer/proxy.","solutions":["Check vm-monitor to compute-node postgres connection health and retry the operation","If in a test, make the mocked query client return one row for `SELECT pg_size_bytes(current_setting('neon.file_cache_size_limit'))`","Inspect logs for the preceding `failed to query pg for file cache size` context to find the underlying connection error","Verify you are connected to a Neon compute node where the `neon.file_cache_size_limit` GUC exists"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match filecache.get_file_cache_size().await {\n    Ok(size) => { /* use size */ }\n    Err(e) if e.to_string().contains(\"no rows\") => {\n        // scalar SELECT returning nothing is a transport anomaly: reconnect and retry\n        reconnect().await?;\n        let size = filecache.get_file_cache_size().await?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Monitor connection pool health between vm-monitor and postgres","In tests, always program mocked SQL clients with a row for scalar settings queries","Treat zero rows on a scalar SELECT as a connection red flag, never as a normal value"],"tags":["rust","neon","vm-monitor","postgres","sqlx"],"backgroundTag":"sql-query-returned-no-rows","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}