Follow-up from review on #875. When a :param route receives a path segment that fails axum's Path extraction (e.g. invalid percent-encoding like /mcp/%ff), the extractor's built-in 400 response bypasses the handler entirely — no access log line, no proxy-style envelope, no reject telemetry. That is the same class of silent pre-dispatch rejection #863 collected into crate::reject for auth/method early exits.
This is not specific to the new /mcp/{server} route: /a2a/:agent, /v1/files/:id, /v1/batches/:id, /v1/fine_tuning/jobs/:id, /v1/videos/:id and /passthrough/:provider/*rest share the identical gap, so per the handler-family rule it should be fixed once for the whole family (e.g. a shared Result<Path<T>, PathRejection> pattern routed through reject::reject_before_dispatch, or a rejection-mapping layer) rather than patched on one endpoint. Impact is limited to malformed-URL observability — no auth or routing consequence.
Follow-up from review on #875. When a
:paramroute receives a path segment that fails axum'sPathextraction (e.g. invalid percent-encoding like/mcp/%ff), the extractor's built-in 400 response bypasses the handler entirely — no access log line, no proxy-style envelope, no reject telemetry. That is the same class of silent pre-dispatch rejection #863 collected intocrate::rejectfor auth/method early exits.This is not specific to the new
/mcp/{server}route:/a2a/:agent,/v1/files/:id,/v1/batches/:id,/v1/fine_tuning/jobs/:id,/v1/videos/:idand/passthrough/:provider/*restshare the identical gap, so per the handler-family rule it should be fixed once for the whole family (e.g. a sharedResult<Path<T>, PathRejection>pattern routed throughreject::reject_before_dispatch, or a rejection-mapping layer) rather than patched on one endpoint. Impact is limited to malformed-URL observability — no auth or routing consequence.