jdx/mise · error

incoming setup deletes required source

Error message

incoming setup deletes required source {}

What it means

Thrown in sources() when the incoming setup explicitly deletes a source file (recorded as Some(None): path exists in the base tree but is removed in the incoming tree) that the batch still requires. Allowing it would leave a required dependency missing after the batch is applied.

Solutions

  1. Restore the deleted file in the shared branch or update the dependent configuration to stop requiring it
  2. Commit the consistency fix upstream and re-pull
  3. Coordinate with the setup author so deletions and requirements land together

Example fix

# before: incoming commit runs `git rm required/env.sh` while another file requires it
# after: keep the file, or update the requiring config's sources to drop required/env.sh
Defensive patterns

Strategy: validation

Validate before calling

# ensure no required source is deleted in the incoming diff
git diff --name-only --diff-filter=D base..incoming | while read -r f; do
  grep -q "$f" required-sources.txt && echo "deleted but required: $f"
done

Prevention

When it happens

Trigger: The incoming commit removes a file that other incoming configuration lists as a required source; sources() encounters Some(None) for that path.

Common situations: A teammate refactored the shared setup, deleting a file that another file in the same setup still depends on; a partial migration left dangling requirements.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/5e2e1c31a08edf0a. Report an issue: GitHub.

Appendix: source

Thrown at src/system/history/sync/preflight.rs:149

/// 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 => {}
        }
    }
    Ok(())
}

fn has_incoming_child(roots: &Roots, path: &Path, plans: &[PathPlan]) -> bool {
    plans.iter().any(|plan| {
        plan.apply.as_ref().is_some_and(Option::is_some)

View on GitHub (pinned to 533346cc37)