EpicGames/lore · critical
Failed to create hooks from configuration
Error message
Failed to create hooks from configuration
What it means
A `.expect("Failed to create hooks from configuration")` panic in the server startup path (`async_main`, invoked from `server_main`) when `hook_registry.create_enabled_hooks(&settings.hooks)` returns Err. This converts an invalid hooks configuration into a hard startup failure: the server refuses to boot rather than run with broken hooks.
Solutions
- Read the Err returned by create_enabled_hooks (replace expect temporarily or check logs) to see which hook name failed
- Fix the `hooks` section of the server settings file — correct hook names and required fields
- Confirm the hook's registration callback is registered so a factory exists for every enabled hook
- After upgrading, migrate the hooks config to the current schema
- Disable the offending hook to boot the server, then fix its configuration
Example fix
// before
let enabled_hooks = hook_registry
.create_enabled_hooks(&settings.hooks)
.expect("Failed to create hooks from configuration");
// after
let enabled_hooks = hook_registry.create_enabled_hooks(&settings.hooks)
.unwrap_or_else(|e| {
eprintln!("invalid hooks configuration: {e:?}");
std::process::exit(1);
}); Defensive patterns
Strategy: validation
Validate before calling
// Validate hooks config before startup
for (name, hook_cfg) in &settings.hooks {
if !hook_registry.has_factory(name) {
return Err(format!("unknown hook '{name}' in configuration"));
}
hook_registry.validate_hook_config(name, hook_cfg)?;
} Try / catch
let enabled_hooks = hook_registry.create_enabled_hooks(&settings.hooks)
.map_err(|e| format!("hook configuration error: {e}"))?; Prevention
- Validate the hooks config section at config-load time, before spawning the server
- After upgrades, run the config through the current schema/migration
- Keep hook registration callbacks registered before create_enabled_hooks is called
When it happens
Trigger: `settings.hooks` names a hook type that has no registered factory (registration callbacks didn't register it), or a hook's configuration section fails that hook's own config validation (missing/invalid fields, bad types, bad URLs/paths).
Common situations: Typo'd or renamed hook entries in the server config file after a version upgrade; enabling a built-in hook that was removed or moved behind a feature flag; hook config schema changed between versions so old settings no longer validate; a custom hook's registration callback not running before this call.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Failed to open log file
- {e}
- Networking not supported on this OS
- [environment.endpoint] auth_url is set but [server.auth] is…
- [environment.endpoint] auth_url and [server.auth]…
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/5ae044d221016dbc.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/server.rs:1903
&settings.notification,
local_store().as_ref(),
&settings.plugins,
)
.await?;
// Build hook dispatcher: register build.rs-discovered hooks then config-provided hooks
let hook_ctx = HookRegistrationContext {
notification_sender: notification.clone(),
};
let mut hook_registry = HookRegistry::new();
crate::hooks::register_all_hooks(&mut hook_registry, &hook_ctx);
for callback in config.hook_registration_callbacks {
callback(&mut hook_registry, &hook_ctx);
}
let enabled_hooks = hook_registry
.create_enabled_hooks(&settings.hooks)
.expect("Failed to create hooks from configuration");
let hook_dispatcher = Arc::new(HookDispatcher::from_hooks_default(enabled_hooks));
lore_spawn!(endpoints, {
let immutable_store = immutable_store.clone();
let mutable_store = mutable_store.clone();
let lock_store = lock_store.clone();
let jwt_verifier = jwt_verifier.clone();
let repository_authorizer = repository_authorizer.clone();
let settings = settings.clone();
let notification = notification.clone();
let user_agent_filter = user_agent_filter.clone();
let forwarded_requests = forwarded_requests.clone();
let shutdown_rx = _shutdown_rx.clone();
let local_immutable_store = local_store().unwrap_or_else(|| {
warn!("No local store available for gRPC server, operations requiring local store will route to the main store");
immutable_store.clone()View on GitHub (pinned to 074eb0b0d1)