cube-js/cube · error

Service not found: {}

Error message

Service not found: {}

What it means

After the init-guard phase, get_service falls back to the factories map to construct a lazily-initialized service. If no factory is registered under the requested name, it panics 'Service not found'. Like error 556, it reflects missing DI registration.

Source

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

        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
            .insert(name.to_string(), service.clone());
        service.clone().downcast(service).unwrap()
    }

    pub async fn try_get_service<T: ?Sized + Send + Sync + 'static>(
        &self,
        name: &str,
    ) -> Option<Arc<T>> {
        self.services
            .read()
            .await
            .get(name)
            .map(|s| s.clone().downcast(s.clone()).unwrap())

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Register the factory for the service name via the injector's add_factory/registration API
  2. Make both registration and lookup use the same shared service-name constant
  3. Trace which code path requests the service and align the startup wiring

Example fix

// before
injector.add_init_guard(ORDER_SERVICE, ...); // factory missing
// after
injector.add_init_guard(ORDER_SERVICE, ...);
injector.add_factory(ORDER_SERVICE, |injector| async move { Ok(Arc::new(OrderService::new(injector))) });
Defensive patterns

Strategy: validation

Validate before calling

// Boot-time self-check that every declared service has a factory
pub async fn verify_factories(injector: &Injector, names: &[&str]) {
    for n in names {
        if !injector.has_factory(n).await {
            panic!("No factory registered for service '{}'", n);
        }
    }
}

Prevention

When it happens

Trigger: get_service called for a name present in init_guards but whose factory was never added to self.factories — e.g. a service initialized but never given a factory, or name mismatch between registration and lookup.

Common situations: Adding a service's init guard during refactoring but forgetting the factory closure; renaming service constants so registration and lookup keys diverge.

Related errors


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