diesel-rs/diesel · error
Can't get file name from path
Error message
Can't get file name from path `{path:?}` What it means
This panic comes from diesel's `embed_migrations!` proc macro when building migration entries at compile time. `migration_literal_from_path` calls `Path::file_name()` on each entry in the migrations directory; `file_name()` returns None for paths ending in `..` or a filesystem root, so the macro panics instead of producing a migration name. It means the macro was given a path component from which no file/directory name can be extracted.
Solutions
- Pass a concrete, normalized migrations directory path to `embed_migrations!`, e.g. `embed_migrations!("migrations")`, not `.` or paths containing `..`.
- Verify at `CARGO_MANIFEST_DIR` level that the directory exists and its entries are real subdirectories (e.g. `migrations/2023-01-01-000000_create_users`).
- Run `diesel migration generate <name>` to create correctly shaped migration directories instead of hand-creating them.
- If the path is computed dynamically in a build script, canonicalize it (remove `.`/`..`) before embedding.
Example fix
// before
embed_migrations!("./migrations/..");
// after
embed_migrations!("migrations"); Defensive patterns
Strategy: validation
Validate before calling
let dir = std::path::Path::new("migrations");
assert!(dir.is_dir(), "migrations dir missing");
assert!(dir.file_name().is_some(), "path must end in a real directory name, not '.' or '..'"); Type guard
fn has_file_name(p: &std::path::Path) -> bool { p.file_name().is_some() } Prevention
- Always pass a literal, normalized migrations directory to embed_migrations!.
- Never use `.` or `..` components in the macro argument.
- Generate migrations with `diesel migration generate` instead of hand-crafting folders.
When it happens
Trigger: Calling `embed_migrations!` (or `embed_migrations!("path")`) with a path that resolves to `.`/`..` segments, a trailing path that reduces to a root, or a directory entry yielded by `read_dir` whose path has no final component.
Common situations: Pointing the macro at `"."` or `"migrations/.."`; build scripts or IDE-provided relative paths with `..` components; misconfigured MIGRATION_DIRECTORY env-style variables; moving the macros crate call so the implicit migrations path no longer exists as expected.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid migration directory: the directory's name should be
- Failed to create embedded migrations instance
- ` ` must be in the form `#[ ="something"]
- expected a integer literal expression, but got something…
- no `#[diesel(sql_type = ...)]` attribute provided
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/a063824d3b414f28.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_migrations/migrations_macros/src/embed_migrations.rs:42
}
fn migration_literals_from_path(
path: &Path,
) -> Result<Vec<proc_macro2::TokenStream>, Box<dyn Error>> {
let mut migrations = migrations_directories(path)?.collect::<Result<Vec<_>, _>>()?;
migrations.sort_by_key(DirEntry::path);
Ok(migrations
.into_iter()
.map(|e| migration_literal_from_path(&e.path()))
.collect())
}
fn migration_literal_from_path(path: &Path) -> proc_macro2::TokenStream {
let name = path
.file_name()
.unwrap_or_else(|| panic!("Can't get file name from path `{path:?}`"))
.to_string_lossy();
if version_from_string(&name).is_none() {
panic!(
"Invalid migration directory: the directory's name should be \
<timestamp>_<name_of_migration>, and it should contain \
up.sql and optionally down.sql."
);
}
let up_sql_path = path.join("up.sql");
let up_sql_path = up_sql_path.to_str();
let down_sql_path = path.join("down.sql");
let metadata = TomlMetadata::read_from_file(&path.join("metadata.toml")).unwrap_or_default();
let run_in_transaction = metadata.run_in_transaction;
let down_sql = match down_sql_path.metadata() {
Err(e) if e.kind() == std::io::ErrorKind::NotFound => quote! { None },
_ => {
let down_sql_path = down_sql_path.to_str();View on GitHub (pinned to 6fa6ed01b2)