jdx/mise · error
incoming configuration must be a regular file
Error message
incoming configuration must be a regular file: {} What it means
Thrown during prospective preflight of incoming history-sync configuration when a git entry being pulled from the shared origin has an invalid mode: it is neither a regular file (100644) nor an executable file (100755). mise refuses to treat symlinks, gitlinks (submodules), or other non-regular objects as installable configuration.
Solutions
- Replace the symlink/submodule with a regular file in the shared setup and commit
- Remove the offending entry from the shared branch if it should not be distributed
- Ask the setup author to commit the actual file contents instead of a link
- Pull again after the upstream branch is fixed
Example fix
# before (in shared repo) ln -s ~/real-config.toml mise.toml && git add mise.toml # after rm mise.toml && cp ~/real-config.toml mise.toml && git add mise.toml
Defensive patterns
Strategy: validation
Validate before calling
mode=$(git ls-tree HEAD -- <path> | awk '{print $1}')
[[ "$mode" == "100644" || "$mode" == "100755" ]] || echo "replace symlink/submodule at <path> with a regular file" Prevention
- Never commit symlinks or submodules inside directories distributed by the shared setup
- Check `git ls-files -s` for unexpected modes (120000/160000) before pushing
- Commit real file contents, not links, for shared configuration
When it happens
Trigger: The incoming branch/commit records a config path as a symlink (120000), submodule gitlink (160000), or other exotic mode while prospective() enumerates files to install.
Common situations: A teammate committed a symlinked config file; a submodule was accidentally added inside the shared config directory; the shared repo contains a directory entry where a 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
- incoming setup deletes required source
- required source is not a regular file
- cannot onboard this setup repository: history is unavailable
- configuration disappeared from preview commit
- could not snapshot the local history repository for preview
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/aac9982b93b4a8c5.
Report an issue: GitHub.
Appendix: 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 dot 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 533346cc37)