{"record":{"id":"3c571c6dcfb6feb8","repo":"jdx/mise","slug":"edits-cannot-unapply-these-entries","errorCode":null,"errorMessage":"edits: cannot unapply these entries:\n{}","messagePattern":"edits: cannot unapply these entries:\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/edits.rs","lineNumber":944,"sourceCode":"            },\n            EditOp::Line { line, .. } if lines.contains(&line.as_str()) => {\n                if !opts.force {\n                    problems.push(format!(\n                        \"  \\\"{}\\\" ({}): line edits have no ownership marker; use --force to remove the line\",\n                        req.path_raw,\n                        req.describe_op()\n                    ));\n                } else if seen_lines.insert((req.path.clone(), line.clone())) {\n                    // Two ids with the same line converge to one applied line\n                    // and therefore produce one unapply action.\n                    todo.push(UnapplyPlan { req, text });\n                }\n            }\n            EditOp::Line { .. } => {}\n        }\n    }\n    if !problems.is_empty() {\n        bail!(\n            \"edits: cannot unapply these entries:\\n{}\",\n            problems.join(\"\\n\")\n        );\n    }\n    Ok(todo)\n}\n\n/// Ensure template functions or another concurrent actor did not invalidate\n/// any edit ownership checks performed during planning.\npub(crate) fn validate_unapply(todo: &[UnapplyPlan<'_>]) -> Result<()> {\n    let mut checked = indexmap::IndexSet::new();\n    let mut problems = vec![];\n    for plan in todo {\n        if !checked.insert(plan.req.path.clone()) {\n            continue;\n        }\n        let result = if plan.req.path.is_symlink() {\n            Err(eyre::eyre!(\"{SYMLINK_REASON}\"))","sourceCodeStart":926,"sourceCodeEnd":962,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/edits.rs#L926-L962","documentation":"plan_unapply builds the list of operations needed to remove managed edits from files. Requests that cannot be unapplied (e.g. target is a symlink, per SYMLINK_REASON) are collected into `problems`; if any exist, mise aborts before touching anything and tells the user to fix those entries manually.","triggerScenarios":"Running an unapply flow (`mise edits unapply` / removing a managed edit) where plan_unapply encounters a request whose precheck fails — classically a target that is a symlink — so no safe unapply plan can be produced for it.","commonSituations":"The user removes an [edits] entry from mise.toml expecting mise to clean the file, but the target became a symlink since the edit was applied (another dotfile manager took over), so unapply refuses.","solutions":["Inspect the listed entries; the usual cause is a target that is now a symlink.","Manually remove the managed block/lines from the symlink's real target file.","Or restore the target to a regular file so mise can unapply it.","Re-run the unapply command; planning will succeed once no problems remain."],"exampleFix":"// before: ~/.zshrc is a symlink; `mise edits unapply` refuses\n// fix manually:\nsed -i '/# mise:begin <id>/,/# mise:end <id>/d' ~/dotfiles/zshrc\n\n// after: entry removed from config and block deleted by hand","handlingStrategy":"validation","validationCode":"# ensure no unapply target is a symlink\nfor f in $(mise edits list-targets); do\n  [ -L \"$f\" ] && echo \"cannot unapply symlink: $f\"\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Un-symlink targets before requesting unapply, or edit the real file manually","Avoid stacking multiple dotfile managers on the same paths","Review planned removals with a dry run before executing"],"tags":["rust","dotfiles","unapply","symlink"],"backgroundTag":"unsupported-operation","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}