jdx/mise · error
incoming configuration must be a regular file: {}
Error message
incoming configuration must be a regular file: {} What it means
During history-sync preflight, mise validates every incoming configuration file from the shared repository before applying it. Git tree entries carry a mode, and only regular files (modes 100644 and 100755) can be parsed as TOML configuration. If an incoming path is a symlink (120000), submodule (160000), or gitlink, mise refuses to continue rather than silently skipping or misinterpreting it.
Source
Thrown at src/system/history/sync/preflight.rs:51
if incoming.is_empty() {
return Ok(tracked.clone());
}
let paths: BTreeSet<PathBuf> = incoming.keys().cloned().collect();
let candidates = crate::config::config_files_with_incoming(&roots.config_dir, &paths);
// Validate every body we will write, even a conf.d file not selected
// by this machine's explicit MISE_GLOBAL_CONFIG_FILE override.
let mut incoming_files = ConfigMap::new();
for (path, object) in &incoming {
// The config directory also carries template and other sources.
if !candidates.contains(path) && crate::env::MISE_GLOBAL_CONFIG_FILE.as_ref() != Some(path)
{
continue;
}
let Some((mode, oid)) = object else {
continue;
};
if mode != "100644" && mode != "100755" {
bail!(
"incoming configuration must be a regular file: {}",
path.display()
);
}
let body = String::from_utf8(repo.cat_object(oid)?)?;
let parsed = MiseToml::for_history_preflight(&body, path)?;
if parsed
.history_config()
.is_some_and(|history| history.origin.is_some())
{
bail!(
"incoming history.origin is machine-local configuration; remove it from the shared setup and use `mise bootstrap dotfiles origin set` on this machine ({})",
path.display()
);
}
incoming_files.insert(
path.clone(),
Arc::new(parsed) as Arc<dyn crate::config::config_file::ConfigFile>,View on GitHub (pinned to afd2eddd3a)
Solutions
- Replace the symlink/submodule with a real regular file: `git rm --cached <path>` then copy the target content into the path and commit with mode 100644/100755.
- If the config is genuinely shared elsewhere, vendor its contents into the repository instead of linking.
- Pull the corrected upstream commit (or reset to a good revision) and rerun the sync/preflight.
Example fix
// before (in the shared repo) ln -s ~/real-mise.toml mise.toml && git add mise.toml # mode 120000 // after cp ~/real-mise.toml mise.toml && git add mise.toml # mode 100644
Defensive patterns
Strategy: validation
Validate before calling
const mode = treeEntry.mode;
if (mode !== "100644" && mode !== "100755") {
throw new Error(`incoming configuration must be a regular file: ${path}`);
} Type guard
function isRegularFileMode(mode: string): boolean {
return mode === "100644" || mode === "100755";
} Try / catch
try {
await syncPull();
} catch (e) {
if (String(e.message).includes("must be a regular file")) {
console.error(`Fix non-file entry in shared repo: ${e.message}`);
} else throw e;
} Prevention
- Never commit symlinks for config paths in the shared dotfiles repository; commit real files.
- Avoid adding git submodules inside the config directory.
- Add a CI lint that rejects tree entries with modes other than 100644/100755 under config paths.
When it happens
Trigger: A commit in the dotfiles/config repository sets a configuration path (a path matched by is_configuration, e.g. a mise.toml or conf.d file) to a non-blob object: a symlink entry (mode 120000), a git submodule entry (160000), or any other non-regular mode. Raised in `prospective` when iterating planned applies and checking `mode != "100644" && mode != "100755"`.
Common situations: A teammate symlinked mise.toml to a file outside the repo (e.g. `ln -s ~/dotfiles/mise.toml mise.toml`); someone added a git submodule inside the config directory; a tool vendored a directory entry where a config file was expected.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- [dotfiles]."{req.target_raw}": mode symlink-each requires a
- required source is not a regular file: {}
- [dotfiles]."{}": mode symlink-each requires a directory sour
- managed path '{}' notifies unconfigured bootstrap service '{
- managed path '{}' notifies unconfigured bootstrap service '{
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/aac9982b93b4a8c5.
Report an issue: GitHub.