{"record":{"id":"2ffbc80402ecc068","repo":"nikivdev/code","slug":"external-cli-is-already-linked-to-use-for","errorCode":null,"errorMessage":"external CLI {} is already linked to {} (use --force to replace it)","messagePattern":"external CLI (.+?) is already linked to (.+?) \\(use --force to replace it\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/external_cli.rs","lineNumber":146,"sourceCode":"        .with_context(|| format!(\"failed to resolve {}\", manifest_path.display()))?;\n    let manifest = read_manifest(&manifest_path)?;\n\n    let record = ExternalCliLinkRecord {\n        version: LINK_RECORD_VERSION,\n        id: manifest.id.clone(),\n        source_root,\n        manifest_path,\n        installed_at: Utc::now().to_rfc3339(),\n        description: manifest.description.clone(),\n    };\n\n    let links_dir = ensure_link_records_dir()?;\n    let record_path = links_dir.join(format!(\"{}.toml\", record.id));\n\n    if record_path.is_file() {\n        let existing = read_link_record(&record_path)?;\n        if !same_link_target(&existing, &record) && !force {\n            bail!(\n                \"external CLI {} is already linked to {} (use --force to replace it)\",\n                record.id,\n                existing.source_root.display()\n            );\n        }\n    }\n\n    let content = toml::to_string_pretty(&record)\n        .with_context(|| format!(\"failed to serialize {}\", record.id))?;\n    fs::write(&record_path, content)\n        .with_context(|| format!(\"failed to write {}\", record_path.display()))?;\n\n    resolved_from_link_record(&record, Some(record_path))\n}\n\npub fn command_for_external_cli<I, S>(\n    id: &str,\n    args: I,","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/external_cli.rs#L128-L164","documentation":"install_external_cli_link records each external CLI link as a TOML file named <id>.toml. If a record already exists for the id and its source_root differs from the new link target, it refuses to silently repoint the link unless --force is passed.","triggerScenarios":"Linking an external CLI id that is already linked to a different source_root with force=false; re-pointing an existing link after moving the source checkout; id collision between two different externals.","commonSituations":"Moving or renaming the external's source directory then re-running the link command; rebuilding links after a config change; two projects deriving the same CLI id.","solutions":["Re-run the link command with --force to deliberately replace the existing link target.","Delete the stale record at the links directory (<id>.toml) and link again.","Use a different id if the two externals are genuinely distinct."],"exampleFix":"// before\ninstall_external_cli_link(&record, false)?;\n// after (intentional re-link)\ninstall_external_cli_link(&record, true)?; // equivalent of --force","handlingStrategy":"validation","validationCode":"// Read the existing record before linking\nlet existing = read_link_record(&links_dir.join(format!(\"{}.toml\", record.id)));\nif let Ok(rec) = &existing {\n    if rec.source_root != record.source_root && !force {\n        return Err(anyhow!(\"{} already linked to {}; pass force to replace\", record.id, rec.source_root.display()));\n    }\n}\ninstall_external_cli_link(&record, force)?;","typeGuard":"fn link_target_matches(existing: &LinkRecord, desired: &LinkRecord) -> bool {\n    same_link_target(existing, desired)\n}","tryCatchPattern":"match install_external_cli_link(&record, false) {\n    Err(e) if e.to_string().contains(\"already linked\") => {\n        eprintln!(\"Re-link intentionally with --force, or remove the stale record\");\n    }\n    r => r?,\n}","preventionTips":["Pass --force explicitly whenever you intentionally move a source checkout.","Keep external source paths stable; avoid renaming/moving linked directories.","Ensure CLI ids are unique across projects to prevent record collisions."],"tags":["configuration","duplicate-link","cli"],"backgroundTag":"link-already-exists","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}