jdx/mise · error
required source is not a regular file
Error message
required source is not a regular file: {} What it means
Thrown in sources() preflight when a source file required by the batch resolves in the incoming plans to a git object whose mode is not a regular/executable file (100644/100755). The required dependency must be a real file; symlinks and gitlinks are rejected.
Solutions
- Replace the symlink/submodule with a regular file at the required source path in the shared repo and commit
- Remove the path from the setup's required sources if it is not actually needed
- Re-pull after the upstream fix
Example fix
# before ln -s templates/env.sh required/env.sh && git add required/env.sh # after cp templates/env.sh required/env.sh && git add required/env.sh
Defensive patterns
Strategy: validation
Validate before calling
for src in "${required_sources[@]}"; do
mode=$(git ls-tree HEAD -- "$src" | awk '{print $1}')
[[ "$mode" == 100644 || "$mode" == 100755 ]] || echo "$src is not a regular file"
done Prevention
- Commit required sources as real files, never symlinks/submodules
- Review `git ls-files -s` output for source directories before merging
- Test the shared setup on a clean clone so missing/odd entries surface early
When it happens
Trigger: A required source path has an incoming plan whose apply entry records mode 120000 (symlink) or 160000 (gitlink); sources() cat-checks the blob after the mode test fails.
Common situations: Shared setup commits a symlink where a required source file should be; submodule accidentally created at a source path.
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 configuration must be a regular file
- incoming setup deletes required source
- 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/3830b1edeab03ed0.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/sync/preflight.rs:142
// The repository inventory, not a source or output mentioned by incoming
// configuration, determines which files the batch may install.
let mut prospective = tracked.clone();
prospective.required_sources = declarations.required_sources;
Ok(prospective)
}
/// Required source files must exist in the complete proposed write set or
/// already be available locally. A queued deletion is not an available source.
pub(super) fn sources(repo: &HistoryRepo, tracked: &TrackedSet, plans: &[PathPlan]) -> Result<()> {
let roots = Roots::current();
for source in &tracked.required_sources {
let planned = plans
.iter()
.find(|plan| roots.locate(&plan.branch_path).path() == Some(source.as_path()));
match planned.and_then(|plan| plan.apply.as_ref()) {
Some(Some((mode, oid))) => {
if mode != "100644" && mode != "100755" {
bail!(
"required source is not a regular file: {}",
source.display()
);
}
repo.cat_object(oid)?;
}
Some(None) => bail!(
"incoming setup deletes required source {}",
source.display()
),
None if !source.exists() && !has_incoming_child(&roots, source, plans) => {
bail!(
"incoming setup is missing required source {}",
source.display()
);
}
None => {}
}View on GitHub (pinned to 533346cc37)