astrid-runtime/astrid · error · io::Error
principal .config path is not a regular directory
Error message
principal .config path is not a regular directory
What it means
Thrown by AstridDirs::ensure in crates/astrid-core/src/dirs.rs:850 when the principal .config directory path exists but symlink_metadata reports it is not a directory. ensure() wants to tighten permissions on an existing config dir; if the path is a regular file, symlink, or other non-directory, it aborts with InvalidData rather than clobbering it.
Source
Thrown at crates/astrid-core/src/dirs.rs:850
#[cfg(not(windows))]
std::fs::create_dir_all(dir)?;
}
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = std::fs::Permissions::from_mode(0o700);
std::fs::set_permissions(&self.root, perms.clone())?;
// Secure the two top-level dot-dirs.
std::fs::set_permissions(self.root.join(".local"), perms.clone())?;
// `.config/` is retained only when a legacy migration left it in
// place. Fresh homes do not create it merely for env storage.
let config_dir = self.config_dir();
match std::fs::symlink_metadata(&config_dir) {
Ok(metadata) if metadata.is_dir() => {
std::fs::set_permissions(config_dir, perms)?;
},
Ok(_) => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"principal .config path is not a regular directory",
));
},
Err(error) if error.kind() == io::ErrorKind::NotFound => {},
Err(error) => return Err(error),
}
}
Ok(())
}
// ── Path accessors ───────────────────────────────────────────────
/// Principal home root (`home/{principal}/`).
#[must_use]
pub fn root(&self) -> &Path {
&self.root
}View on GitHub (pinned to affd8760f4)
Solutions
- Replace the non-directory at the config path with a real directory (move the file aside, mkdir the path, restore contents).
- Remove the symlink and let ensure() create a genuine directory, then re-link contents individually rather than the whole path.
- Check `ls -la` / symlink_metadata on config_dir before install and fix its type.
- Point Astrid's config_dir setting at a valid directory if the current path was misconfigured.
Example fix
# before $ ls -la ~/.config .config -> dotfiles/config # symlink error: principal .config path is not a regular directory # after $ rm ~/.config $ mkdir ~/.config $ cp -r dotfiles/config/. ~/.config/
Defensive patterns
Strategy: validation
Validate before calling
// Rust
fn config_dir_ok(config_dir: &Path) -> bool {
match std::fs::symlink_metadata(config_dir) {
Ok(md) => md.is_dir(),
Err(e) => e.kind() == io::ErrorKind::NotFound, // absent is fine
}
} Type guard
fn is_real_directory(path: &Path) -> bool {
std::fs::symlink_metadata(path).map(|md| md.is_dir()).unwrap_or(false)
} Try / catch
match ensure_result {
Err(e) if e.kind() == io::ErrorKind::InvalidData
&& e.to_string().contains("not a regular directory") => {
// move the file/symlink aside, mkdir the path, retry
}
r => r?,
} Prevention
- Ensure ~/.config is a real directory, not a file or whole-path symlink
- Configure dotfile managers to link individual entries, not .config itself
- Check symlink_metadata on config paths before running install/sign flows
- Restore config directories as directories, not loose files
When it happens
Trigger: Calling ensure() (directly or via install/sign-archive flows like sign_archive_with_runtime_key_in_home) when ~/.config or the configured config_dir is a plain file or symlink — e.g. a config file was created where a directory belongs, or a dotfile manager symlinked the path.
Common situations: Dotfile managers (GNU Stow, chezmoi) symlinking .config to a repo; a stray 'config' file created by a misconfigured tool; partial restore placing a tar of files at the config path.
Related errors
- legacy capsule authority root is not a regular directory: {}
- legacy capsule authority root is not a regular directory: {}
- legacy capsule authority root contains a non-regular entry:
- leftover capsule authority receipt is not a regular file: {}
- legacy capsule authority root contains a non-regular entry:
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/a05a1efb069dbfbc.
Report an issue: GitHub.