cube-js/cube · error

Service is not found: {}

Error message

Service is not found: {}

What it means

CubeSQL uses a service injection container. get_service looks up an init guard for the named service before initialization; if the service name was never registered (no init guard exists), it panics 'Service is not found'. This indicates a DI wiring/registration bug rather than a runtime condition.

Source

Thrown at rust/cubesql/cubesql/src/config/injection.rs:106

        self.init_guards
            .write()
            .await
            .insert(name.to_string(), Arc::new(Mutex::new(())));
    }
}

impl Injector {
    pub async fn get_service<T: ?Sized + Send + Sync + 'static>(&self, name: &str) -> Arc<T> {
        if let Some(s) = self.try_get_service(name).await {
            return s;
        }

        let pending = self
            .init_guards
            .read()
            .await
            .get(name)
            .unwrap_or_else(|| panic!("Service is not found: {}", name))
            .clone();
        // println!("Locking service: {}", name);
        // TODO cycle depends lead to dead lock here
        let _l = pending.lock().await;

        if let Some(s) = self.try_get_service(name).await {
            return s;
        }

        let factories = self.factories.read().await;
        let factory = factories
            .get(name)
            .unwrap_or_else(|| panic!("Service not found: {}", name));
        let service = factory(self.this.upgrade().unwrap()).await;
        // println!("Setting service: {}", name);
        self.services
            .write()
            .await

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Ensure the service factory is registered (inject/factory map) before any get_service call for that name
  2. Verify the service name string matches the registered key exactly
  3. Check startup ordering — registration must happen before dependent services resolve

Example fix

// before
let meta: Arc<MetaService> = injector.get_service_typed(META_SERVICE).await;
// after
injector.add_factory(META_SERVICE, move |injector| { ... });
let meta: Arc<MetaService> = injector.get_service_typed(META_SERVICE).await;
Defensive patterns

Strategy: validation

Validate before calling

// Verify a service is registered before resolving it
pub async fn assert_registered(injector: &Injector, name: &str) {
    if !injector.has_service_or_guard(name).await {
        panic!("Bug: service '{}' must be registered before use", name);
    }
}

Try / catch

// Panic is intentional for wiring bugs; fix at startup rather than catching.
// Optionally validate all required services at boot:
for name in REQUIRED_SERVICES {
    injector.get_service_typed::<dyn Any>(name).await
        .unwrap_or_else(|e| panic!("startup DI check failed for {}: {:?}", name, e));
}

Prevention

When it happens

Trigger: get_service/get_service_typed called with a service name that was never added to the injector's init_guards; accessing a service before inject() registered it, or a typo'd service name in configuration wiring.

Common situations: Custom CubeSQL builds where a new service was used without registering its factory; refactors that renamed a service key but missed one lookup site; cyclic dependency comments nearby hint at ordering issues.

Related errors


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