tokio-rs/axum · error · compile_error
can't infer state type, please add `#[{attr_name}(state = My
Error message
can't infer state type, please add `#[{attr_name}(state = MyStateType)]` attribute What it means
Emitted by the `#[derive(FromRequest)]` / `#[derive(FromRequestParts)]` proc macros after the macro scans the struct's fields and finds two or more _different_ candidate state types (each `State<T>` field, or each field with `#[from_request(via(State))]`, contributes one). The macro enters the `State::CannotInfer` branch (from_request/mod.rs:129) and, at the end of expansion (line 149), emits this compile_error alongside the generated `impl`. Because a derive cannot prompt at runtime, it asks the developer to disambiguate with a container-level `#[from_request(state = MyStateType)]` attribute.
Source
Thrown at axum-macros/src/from_request/mod.rs:154
fields,
&via,
rejection.as_ref(),
generic_ident.as_ref(),
&state,
tr,
)?,
(None, rejection) => {
error_on_generic_ident(generic_ident, tr)?;
impl_struct_by_extracting_each_field(&ident, &fields, rejection, &state, tr)?
}
};
if matches!(state, State::CannotInfer) {
let attr_name = match tr {
Trait::FromRequest => "from_request",
Trait::FromRequestParts => "from_request_parts",
};
let compile_error = syn::Error::new(
Span::call_site(),
format_args!(
"can't infer state type, please add \
`#[{attr_name}(state = MyStateType)]` attribute",
),
)
.into_compile_error();
Ok(quote! {
#trait_impl
#compile_error
})
} else {
Ok(trait_impl)
}
}
syn::Item::Enum(item) => {
let syn::ItemEnum {View on GitHub (pinned to c9a911b799)
Solutions
- Add `#[from_request(state(AppState))]` (or `state = AppState`) on the struct, naming the single top-level router state; sub-states continue to come from `FromRef<AppState>`.
- Reduce the struct to a single `State<T>` field and derive the other values from it via `FromRef` inside a separate extractor or the handler.
- If the fields really do need different router states, split the struct into two extractors — `FromRequest`/`FromRequestParts` can only be implemented against one `S`.
- Verify the field-level `#[from_request(via(State))]` annotations; each such field contributes its own type to inference, so removing a redundant `via(State)` may collapse the set.
Example fix
// before
#[derive(FromRequest)]
struct Extractor {
a: State<AppState>,
b: State<One>,
}
// after
#[derive(FromRequest)]
#[from_request(state(AppState))]
struct Extractor {
a: State<AppState>,
b: State<One>,
} Defensive patterns
Strategy: validation
Validate before calling
// Convention: always pair #[derive(FromRequest)] with an explicit state attribute
// on any struct that has more than one field. Add this module-level assertion
// to fail fast if someone adds a second State<T>:
//
// #[derive(FromRequest)]
// #[from_request(state(AppState))] // <-- always present
// struct Extractor { a: State<AppState>, b: String }
//
// Static check that AppState is clone+send+sync (the bounds the derive emits):
const _: fn() = || {
fn assert_state_bounds<S: Clone + Send + Sync>() {}
assert_state_bounds::<AppState>();
}; Type guard
// Narrowing helper for call sites that must accept only the intended state.
pub trait FromRequestForState {}
impl FromRequestForState for crate::Extractor {}
// Then any generic API can be constrained:
pub fn run<E: FromRequestForState>(_e: E) {}
// Mis-deriving against the wrong state type breaks this impl, not the macro. Prevention
- Always annotate multi-field extractors with `#[from_request(state(...))]` even if inference currently succeeds; future field additions won't break the build.
- Centralize router state in one `AppState` and expose sub-states through `FromRef` so all `State<T>` fields share the same inference target.
- During code review, flag any `#[derive(FromRequest)]` on a struct with >1 `State<T>` field that lacks an explicit `state(...)`.
- Keep the repo's `tests/from_request/fail/state_infer_multiple_different_types.rs` pattern in mind as the canonical anti-example.
When it happens
Trigger: A struct has multiple fields whose types resolve to distinct state inner-types, e.g. `struct E { a: State<AppState>, b: State<OtherState> }` with `#[derive(FromRequest)]` and no container `state(...)` attribute. The inference collects types via `infer_state_type_from_field_types` (line 999) plus `infer_state_type_from_field_attributes` (line 1022); when the resulting `HashSet` has >1 element the `State::CannotInfer` arm fires (line 129) and the compile_error is produced at line 154. Reproducible with the repo's own `tests/from_request/fail/state_infer_multiple_different_types.rs`.
Common situations: Building an extractor that pulls several sub-states out of a shared `AppState` (each via its own `FromRef`) but forgetting that the derive tries to infer one router-level `S`. Splitting a monolithic `AppState` into smaller sub-states and updating extractor fields one-by-one. Migration from a hand-written `impl FromRequestParts` (where the state type was explicit in the signature) to the derive, leaving the field set ambiguous.
Related errors
- missing `#[from_request(via(...))]`
- can't infer state type, please add set it explicitly, as in
- Missing path: `#[typed_path("/foo/bar")]`
- Typed paths for unit structs cannot contain captures
AI-assisted analysis of tokio-rs/axum@c9a911b799 (2026-08-06).
Data as JSON: /data/errors/9ffef49e686975b0.json.
Report an issue: GitHub.