EpicGames/lore · error · anyhow::Error

Missing gRPC settings

Error message

Missing gRPC settings

What it means

Thrown by launch_grpc_server when settings.server.grpc is None. The gRPC server cannot bind to a host/port without its settings block, so startup fails fast instead of proceeding with a half-configured server. This is a startup-time configuration validation error.

Solutions

  1. Add a [server.grpc] section with host and port to the server's TOML config file.
  2. Verify you are loading the intended config file (check config path env var / CLI flag).
  3. Check the Settings struct docs for required server.grpc fields after upgrading versions.

Example fix

# before
[server]
# no grpc section

# after
[server.grpc]
host = "0.0.0.0"
port = 50051
Defensive patterns

Strategy: validation

Validate before calling

if settings.server.grpc.is_none() {
    return Err(anyhow!("server.grpc section missing from config; cannot launch gRPC server"));
}

Type guard

fn grpc_settings_ready(settings: &Settings) -> bool {
    settings.server.grpc.is_some()
}

Prevention

When it happens

Trigger: Calling launch_grpc_server with a Settings value whose settings.server.grpc field is None (the TOML config lacks [server.grpc] or it was not deserialized).

Common situations: Running the server with a config file that omits the [server.grpc] section while the transport expects gRPC; copying a config from a HTTP-only deployment; renaming config keys after a version upgrade so the section silently deserializes as None.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/fffeeb213532eda9. Report an issue: GitHub.

Appendix: source

Thrown at lore-server/src/server.rs:455

    immutable_store: Arc<dyn ImmutableStore>,
    local_store: Arc<dyn ImmutableStore>,
    mutable_store: Arc<dyn MutableStore>,
    lock_store: Option<Arc<dyn LockStore>>,
    jwt_verifier: Option<JwtVerifier>,
    repository_authorizer: Arc<dyn RepositoryAuthorizer>,
    settings: Settings,
    notification_sender: Arc<dyn NotificationSender>,
    notification_service: Option<NotificationService>,
    hook_dispatcher: Arc<HookDispatcher>,
    user_agent_filter: Arc<UserAgentFilter>,
    forwarded_requests: Option<Arc<dyn ForwardedRequests>>,
    mut shutdown_rx: tokio::sync::watch::Receiver<bool>,
) -> Result<()> {
    let grpc_settings = settings
        .server
        .grpc
        .clone()
        .ok_or(anyhow!("Missing gRPC settings"))?;
    let service_settings = settings.server.grpc_public_services.clone();

    let addr =
        SocketAddr::from_str(format!("{}:{}", grpc_settings.host, grpc_settings.port).as_str())?;

    let locks = lock_store.is_some() && service_settings.lock_service.enabled;

    info!(
        "Starting Lore GRPC Server: {}, Auth: {} Locks: {}",
        &addr,
        jwt_verifier.as_ref().map_or("disabled", |_| "enabled"),
        if locks { "enabled" } else { "disabled" },
    );

    // The settings map has no relevant entries to surface yet, so it stays empty.
    // The features list reports the cargo features the binary was compiled with so
    // clients and tests can detect optional capabilities (e.g. failure_generator).
    let settings_map: HashMap<String, String> = HashMap::new();

View on GitHub (pinned to 074eb0b0d1)