{"record":{"id":"aac9982b93b4a8c5","repo":"jdx/mise","slug":"incoming-configuration-must-be-a-regular-file","errorCode":null,"errorMessage":"incoming configuration must be a regular file: {}","messagePattern":"incoming configuration must be a regular file: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/preflight.rs","lineNumber":51,"sourceCode":"    if incoming.is_empty() {\n        return Ok(tracked.clone());\n    }\n    let paths: BTreeSet<PathBuf> = incoming.keys().cloned().collect();\n    let candidates = crate::config::config_files_with_incoming(&roots.config_dir, &paths);\n    // Validate every body we will write, even a conf.d file not selected\n    // by this machine's explicit MISE_GLOBAL_CONFIG_FILE override.\n    let mut incoming_files = ConfigMap::new();\n    for (path, object) in &incoming {\n        // The config directory also carries template and other sources.\n        if !candidates.contains(path) && crate::env::MISE_GLOBAL_CONFIG_FILE.as_ref() != Some(path)\n        {\n            continue;\n        }\n        let Some((mode, oid)) = object else {\n            continue;\n        };\n        if mode != \"100644\" && mode != \"100755\" {\n            bail!(\n                \"incoming configuration must be a regular file: {}\",\n                path.display()\n            );\n        }\n        let body = String::from_utf8(repo.cat_object(oid)?)?;\n        let parsed = MiseToml::for_history_preflight(&body, path)?;\n        if parsed\n            .history_config()\n            .is_some_and(|history| history.origin.is_some())\n        {\n            bail!(\n                \"incoming history.origin is machine-local configuration; remove it from the shared setup and use `mise dot origin set` on this machine ({})\",\n                path.display()\n            );\n        }\n        incoming_files.insert(\n            path.clone(),\n            Arc::new(parsed) as Arc<dyn crate::config::config_file::ConfigFile>,","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/sync/preflight.rs#L33-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before (in shared repo)\nln -s ~/real-config.toml mise.toml && git add mise.toml\n# after\nrm mise.toml && cp ~/real-config.toml mise.toml && git add mise.toml","handlingStrategy":"validation","validationCode":"mode=$(git ls-tree HEAD -- <path> | awk '{print $1}')\n[[ \"$mode\" == \"100644\" || \"$mode\" == \"100755\" ]] || echo \"replace symlink/submodule at <path> with a regular file\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["git","history-sync","preflight"],"backgroundTag":"incompatible-source-type","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}