{"record":{"id":"5e2e1c31a08edf0a","repo":"jdx/mise","slug":"incoming-setup-deletes-required-source","errorCode":null,"errorMessage":"incoming setup deletes required source {}","messagePattern":"incoming setup deletes required source (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/preflight.rs","lineNumber":149,"sourceCode":"/// Required source files must exist in the complete proposed write set or\n/// already be available locally. A queued deletion is not an available source.\npub(super) fn sources(repo: &HistoryRepo, tracked: &TrackedSet, plans: &[PathPlan]) -> Result<()> {\n    let roots = Roots::current();\n    for source in &tracked.required_sources {\n        let planned = plans\n            .iter()\n            .find(|plan| roots.locate(&plan.branch_path).path() == Some(source.as_path()));\n        match planned.and_then(|plan| plan.apply.as_ref()) {\n            Some(Some((mode, oid))) => {\n                if mode != \"100644\" && mode != \"100755\" {\n                    bail!(\n                        \"required source is not a regular file: {}\",\n                        source.display()\n                    );\n                }\n                repo.cat_object(oid)?;\n            }\n            Some(None) => bail!(\n                \"incoming setup deletes required source {}\",\n                source.display()\n            ),\n            None if !source.exists() && !has_incoming_child(&roots, source, plans) => {\n                bail!(\n                    \"incoming setup is missing required source {}\",\n                    source.display()\n                );\n            }\n            None => {}\n        }\n    }\n    Ok(())\n}\n\nfn has_incoming_child(roots: &Roots, path: &Path, plans: &[PathPlan]) -> bool {\n    plans.iter().any(|plan| {\n        plan.apply.as_ref().is_some_and(Option::is_some)","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/preflight.rs#L131-L167","documentation":"A required source file must be available either in the incoming write set or already locally. If the incoming batch explicitly deletes the path (its plan apply is `Some(None)`, i.e. a queued deletion), mise refuses to proceed: a queued deletion is not an available source, and applying the batch would leave the tracked set referencing a missing input.","triggerScenarios":"In `sources`, the plan for a required-source path has `apply == Some(None)` — the incoming repository records a deletion of that file while the current tracked set still lists it as a required source (e.g. a template consumed to render a managed file).","commonSituations":"A teammate deleted a template/source file that other machines' tracked sets still depend on; a rename in the repo removed the old path without updating dependent declarations; a branch reverted the addition of the source file.","solutions":["Restore the deleted source file in the shared repository (git revert the deletion or re-add the content).","If the source is genuinely obsolete, first update/remove the declarations that require it (in the tracked set / config), commit, then pull.","Re-run the sync after pulling a branch where the source exists."],"exampleFix":"// before (incoming commit)\ngit rm .mise/sources/shellrc   # still required by tracked set\n// after\ngit checkout HEAD~1 -- .mise/sources/shellrc && git commit -m \"restore required source\"  # or update dependents first","handlingStrategy":"validation","validationCode":"for (const src of tracked.requiredSources) {\n  const plan = planFor(src);\n  if (plan && plan.apply === null) {\n    throw new Error(`incoming batch deletes required source: ${src}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await applyIncoming();\n} catch (e) {\n  if (String(e.message).startsWith(\"incoming setup deletes required source\")) {\n    console.error(\"Restore the source or update dependent declarations before syncing.\");\n  } else throw e;\n}","preventionTips":["Before deleting a source file in the shared repo, update or remove the declarations that require it in the same commit.","Prefer renaming with a deprecation commit rather than hard deletes.","Review deletions in pull requests for required-source paths."],"tags":["git","sync","deleted-file","state-consistency"],"backgroundTag":"invalid-state-transition","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}