tokio-rs/tokio · error · syn::Error
Failed to parse value of `{field}` as integer.
Error message
Failed to parse value of `{field}` as integer. What it means
Compile-time error emitted by the `parse_int` helper inside the `#[tokio::main]`/`#[tokio::test]` proc-macros. It fires from the `_` arm: the attribute value that must be an integer is not a `syn::Lit::Int`. The only configuration field routed through `parse_int` is `worker_threads` (see `set_worker_threads` calling `parse_int(..., "worker_threads")` in entry.rs:138). The sibling arm (`base10_parse` failure) carries the underlying parse message; this message is the literal-shape mismatch.
Source
Thrown at tokio-macros/src/entry.rs:265
worker_threads,
start_paused,
unhandled_panic,
})
}
}
fn parse_int(int: syn::Lit, span: Span, field: &str) -> Result<usize, syn::Error> {
match int {
syn::Lit::Int(lit) => match lit.base10_parse::<usize>() {
Ok(value) => Ok(value),
Err(e) => Err(syn::Error::new(
span,
format!("Failed to parse value of `{field}` as integer: {e}"),
)),
},
_ => Err(syn::Error::new(
span,
format!("Failed to parse value of `{field}` as integer."),
)),
}
}
fn parse_string(int: syn::Lit, span: Span, field: &str) -> Result<String, syn::Error> {
match int {
syn::Lit::Str(s) => Ok(s.value()),
syn::Lit::Verbatim(s) => Ok(s.to_string()),
_ => Err(syn::Error::new(
span,
format!("Failed to parse value of `{field}` as string."),
)),
}
}
fn parse_path(lit: syn::Lit, span: Span, field: &str) -> Result<Path, syn::Error> {
match lit {
syn::Lit::Str(s) => {View on GitHub (pinned to 625954f365)
Solutions
- Pass an unquoted positive integer literal: `#[tokio::main(flavor = "multi_thread", worker_threads = 8)]`.
- Do not use a Rust `const`/variable — proc-macro attributes only accept literals; if you need runtime values, build the runtime manually with `tokio::runtime::Builder`.
- Double-check there is no `f`/`.`/quotes/suffix on the number.
Example fix
// before
#[tokio::main(worker_threads = "8")]
async fn main() {}
// after
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
async fn main() {} Defensive patterns
Strategy: validation
Prevention
- Pass only unquoted positive integer literals to `worker_threads` (e.g. `worker_threads = 8`).
- Proc-macro attributes only accept literals — never a `const`, `let`, or expression; switch to `runtime::Builder` for runtime-computed thread counts.
- Keep one canonical, copy-pasteable `#[tokio::main(...)]` snippet in the repo to avoid drift.
When it happens
Trigger: Writing `#[tokio::main(worker_threads = "8")]` (a string literal), `worker_threads = 8.0` (a float), `worker_threads = true` (a bool), or `worker_threads = 'a'` (a char). Any token for `worker_threads` that is not an integer literal.
Common situations: Copying a thread-count value quoted as a string from a config file or doc snippet; pasting a float because the source used `8.0`; confusing the macro syntax with runtime `Builder::worker_threads(n)` where `n` is a variable (macros require literals, not identifiers).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse value of `{field}` as string.
- Failed to parse value of `{}` as path: "{}"
- Failed to parse value of `{field}` as path.
- Failed to parse value of `{field}` as bool.
- The #[tokio::main] macro requires rt or rt-multi-thread.
AI-assisted analysis of tokio-rs/tokio@625954f365 (2026-08-11).
Data as JSON: /api/errors/66ac7be016ef8317.
Report an issue: GitHub.