linebender/druid · error
expected str, found... something else
Error message
expected str, found... something else
What it means
parse_lit_into_expr_path converts a literal into a syn::ExprPath and only accepts string literals. When a derive attribute supplies a path value that is not a quoted string (e.g. a bare ident or integer), this compile-time error is raised at the literal's span. The humorous message acknowledges any non-str literal kind.
Solutions
- Quote the path value: use name = "MyPath" instead of name = MyPath.
- Check which options expect string literals in this derive and wrap their values accordingly.
- Inspect the error span — it points at the literal; make that token a string literal.
Example fix
// before #[lens(name = my_lens)] count: usize, // after #[lens(name = "my_lens")] count: usize,
Defensive patterns
Strategy: validation
Validate before calling
fn validate_path_value_is_str(opt_value: &str) -> Result<(), String> {
if opt_value.starts_with('"') && opt_value.ends_with('"') { Ok(()) }
else { Err(format!("path option must be a quoted string, got: {}", opt_value)) }
} Prevention
- Quote every path value in derive attributes: name = "path::Type".
- Never pass bare identifiers or numbers where the derive expects Lit::Str.
- Read the error span — it names the literal that must become a string.
When it happens
Trigger: Passing an unquoted path to an attribute option that expects Lit::Str and is parsed via parse_lit_into_expr_path (called from parse_ast), e.g. a lens/data option given as a bare identifier instead of "identifier".
Common situations: Forgetting quotes around path values in helper attributes, confusing string-valued options with plain path attributes, migrating from crates where paths are written unquoted.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unknown attribute
- Expected attribute list (the form #[data(one, two)])
- Duplicate attribute
- Expected attribute list (the form #[lens(one, two)])
- Data implementations cannot be derived from unions
AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10).
Data as JSON: /api/errors/f7f3577fe41065ef.
Report an issue: GitHub.
Appendix: source
Thrown at druid-derive/src/attr.rs:283
match self.ident {
FieldIdent::Named(ref s) => Ident::new(s, Span::call_site()).into(),
FieldIdent::Unnamed(num) => Literal::usize_unsuffixed(num).into(),
}
}
pub fn ident_string(&self) -> String {
match self.ident {
FieldIdent::Named(ref s) => s.clone(),
FieldIdent::Unnamed(num) => num.to_string(),
}
}
}
fn parse_lit_into_expr_path(lit: &syn::Lit) -> Result<ExprPath, Error> {
let string = if let syn::Lit::Str(lit) = lit {
lit
} else {
return Err(Error::new(
lit.span(),
"expected str, found... something else",
));
};
let tokens = syn::parse_str(&string.value())?;
syn::parse2(tokens)
}
fn parse_lit_into_ident(lit: &syn::Lit) -> Result<Ident, Error> {
let ident = if let syn::Lit::Str(lit) = lit {
Ident::new(&lit.value(), lit.span())
} else {
return Err(Error::new(
lit.span(),
"expected str, found... something else",
));
};View on GitHub (pinned to 0f8b1195e4)