EpicGames/lore · error
ClientIdentify must be handled successfully
Error message
ClientIdentify must be handled successfully
What it means
A Rust test panic from `.expect("ClientIdentify must be handled successfully")` on `StorageServiceV4::run_request_handler` in `run_request_handler_client_identify_returns_empty_ok` (lore-server/src/quic/storage_service_v4.rs:591). A `ParsedStorageRequestV4::ClientIdentify` request was passed to the handler and it returned a `MessageHandleError` instead of an empty success response. The handler must accept ClientIdentify (record user-agent, optionally is_trusted) and return an empty Vec; any Err here means the handler branch is missing, errors on validation, or a dependency it touches (jwt verifier, session map, attribute map) fails.
Solutions
- Show the real error: `.unwrap_or_else(|e| panic!("ClientIdentify handler failed: {e:?}"))` and rerun.
- Add or fix the `ParsedStorageRequestV4::ClientIdentify` arm in `run_request_handler` so it records the user-agent and returns `Vec::new()` (empty ok response).
- Verify the handler doesn't require session/JWT state for ClientIdentify; it should succeed with a default `AttributeMap`.
- If is_trusted validation is intended, allow `is_trusted: false` clients through with a normal (non-error) response.
Example fix
// before
let response = service
.run_request_handler(
Arc::new(AttributeMap::default()),
ParsedStorageRequestV4::ClientIdentify(ci),
)
.await
.expect("ClientIdentify must be handled successfully");
// after
let response = service
.run_request_handler(
Arc::new(AttributeMap::default()),
ParsedStorageRequestV4::ClientIdentify(ci),
)
.await
.unwrap_or_else(|e| panic!("ClientIdentify handler failed: {e:?}")); Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the handler has a ClientIdentify arm before invoking
assert!(
matches!(parsed_request, ParsedStorageRequestV4::ClientIdentify(_)),
"handler test requires a parsed ClientIdentify request"
); Try / catch
let response = service
.run_request_handler(Arc::new(AttributeMap::default()), ParsedStorageRequestV4::ClientIdentify(ci))
.await
.unwrap_or_else(|e| panic!("ClientIdentify handler failed: {e:?}"));
assert!(response.is_empty()); Prevention
- Add the ClientIdentify arm to run_request_handler together with the parser branch.
- Keep ClientIdentify handler dependency-free (no jwt/session requirements).
- Treat is_trusted=false as a normal client unless an explicit allowlist exists.
When it happens
Trigger: Calling `service.run_request_handler(Arc::new(AttributeMap::default()), ParsedStorageRequestV4::ClientIdentify(ci)).await` with `ci = ClientIdentify { user_agent: Some("my-client/1.0"), is_trusted: false }` and the handler returns Err — no ClientIdentify match arm in `run_request_handler`, the arm falls through to a generic error path, or the handler requires session/context state absent from the default AttributeMap.
Common situations: Hit while implementing the ClientIdentify handler (branch not yet added), after `is_trusted` handling was added and now requires a trusted-client allowlist that rejects untrusted clients, or when the handler signature changed from `AttributeMap` to `Arc<AttributeMap>` and dispatch errors on the new type.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- handler failed
- parsing a ClientIdentify request must succeed
- Stream handler factory was not set
- No alpns provided
- Address was not set
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/b448817df50f31cb.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/quic/storage_service_v4.rs:591
#[tokio::test]
async fn run_request_handler_client_identify_returns_empty_ok() {
let (immutable_store, mutable_store, _exec) =
test_store_create().await.expect("Failed to create stores");
let service = make_service(immutable_store, mutable_store);
let ci = crate::protocol::client_identify::ClientIdentify {
user_agent: Some("my-client/1.0".to_string()),
is_trusted: false,
};
let response = service
.run_request_handler(
Arc::new(AttributeMap::default()),
ParsedStorageRequestV4::ClientIdentify(ci),
)
.await
.expect("ClientIdentify must be handled successfully");
assert!(response.is_empty(), "expected empty response vec");
}
/// Fill the session map to capacity then attempt one more `AuthorizeStart`,
/// verifying the handler returns `SlowDown` and that `transform_protocol_error`
/// classifies it the same way `stream_handler` would.
#[tokio::test]
async fn authorize_start_returns_slow_down_when_session_limit_reached() {
let (immutable_store, mutable_store, _execution) =
test_store_create().await.expect("Failed to create stores");
let service = make_service(immutable_store, mutable_store);
let repo = random::<lore_revision::lore::RepositoryId>();
// Fill the session map to capacity via the handler (jwt_verifier is None,
// so each call goes straight to session_map.start with no I/O).View on GitHub (pinned to 074eb0b0d1)