cube-js/cube · error

read_variables is not implemented for custom protocol: {:?}

Error message

read_variables is not implemented for custom protocol: {:?}

What it means

ServerManager keeps session/database variables in a RwLock keyed by protocol. Only PostgreSQL has a variables store; when the connection uses a custom Extension protocol, read_variables panics because extension protocols have no variable storage.

Source

Thrown at rust/cubesql/cubesql/src/sql/server_manager.rs:80

            pg_auth,
            compiler_cache,
            nonce,
            config_obj,
            configuration: ServerConfiguration::default(),
            postgres_variables: RwLockSync::new(postgres_default_global_variables()),
        }
    }

    pub fn read_variables(
        &self,
        protocol: DatabaseProtocol,
    ) -> RwLockReadGuard<'_, DatabaseVariables> {
        match protocol {
            DatabaseProtocol::PostgreSQL => self
                .postgres_variables
                .read()
                .expect("failed to unlock variables for reading"),
            DatabaseProtocol::Extension(ext) => unimplemented!(
                "read_variables is not implemented for custom protocol: {:?}",
                ext
            ),
        }
    }

    fn write_variables(
        &self,
        protocol: DatabaseProtocol,
    ) -> RwLockWriteGuard<'_, DatabaseVariables> {
        match protocol {
            DatabaseProtocol::PostgreSQL => self
                .postgres_variables
                .write()
                .expect("failed to unlock variables for reading"),
            DatabaseProtocol::Extension(ext) => unimplemented!(
                "write_variables is not implemented for custom protocol: {:?}",
                ext

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Guard the call: only read variables when protocol is PostgreSQL; return empty variables for extensions
  2. Initialize a per-extension variables store in ServerManager for the extension protocol
  3. Route the variables request to the extension's own handler instead of server_manager.read_variables
  4. Patch server_manager.rs:80 to return a default empty DatabaseVariables for Extension

Example fix

// before
DatabaseProtocol::Extension(ext) => unimplemented!("read_variables is not implemented for custom protocol: {:?}", ext),
// after
DatabaseProtocol::Extension(_) => self.extension_variables.read().expect("failed to lock variables"),
Defensive patterns

Strategy: type-guard

Validate before calling

fn supports_variables(protocol: &DatabaseProtocol) -> bool {
    matches!(protocol, DatabaseProtocol::PostgreSQL)
}
if supports_variables(&session.protocol()) { vars = mgr.all_variables(...); }

Type guard

fn is_postgres(p: &DatabaseProtocol) -> bool { matches!(p, DatabaseProtocol::PostgreSQL) }

Try / catch

let vars = std::panic::catch_unwind(|| mgr.all_variables(protocol.clone()))
    .map(|g| g.clone())
    .unwrap_or_default(); // empty variables for extension protocols

Prevention

When it happens

Trigger: Calling all_variables (or anything that reads variables) on a session whose DatabaseProtocol is DatabaseProtocol::Extension(ext) — i.e. a custom/extension protocol connection that issues a SHOW or variables query.

Common situations: Implementing a custom CubeSQL extension protocol and a client sends SHOW/SET-style commands; protocol handlers that unconditionally query variables without checking protocol type first.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/e24439b82edcaadd. Report an issue: GitHub.