{"record":{"id":"5ee13444a55b1a44","repo":"astrid-runtime/astrid","slug":"fuse-provider-control-path-is-not-canonical","errorCode":null,"errorMessage":"FUSE provider control path is not canonical","messagePattern":"FUSE provider control path is not canonical","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/main.rs","lineNumber":789,"sourceCode":"async fn require_live_lease(\n    client: &mut AdminClient,\n    acting_principal: &astrid_core::PrincipalId,\n    record: &registry::MountRecord,\n) -> Result<LeaseStatus> {\n    if &record.requested_by != acting_principal {\n        bail!(\"mount was issued to another acting principal\");\n    }\n    kernel_lease_status(client, &record.mount_id)\n        .await?\n        .with_context(|| format!(\"storage mount lease {} is stale\", record.mount_id))\n}\n\nfn validate_record(record: &registry::MountRecord, status: &LeaseStatus) -> Result<()> {\n    if status.mountpoint != record.mountpoint || status.access != record.access {\n        bail!(\"kernel lease metadata does not match the FUSE provider registry\");\n    }\n    if record.control_path != registry::control_path(&record.mount_id)? {\n        bail!(\"FUSE provider control path is not canonical\");\n    }\n    Ok(())\n}\n\nasync fn ensure_mountpoint_available(\n    client: &mut AdminClient,\n    acting_principal: &astrid_core::PrincipalId,\n    mountpoint: &Path,\n) -> Result<()> {\n    let key = mountpoint\n        .to_str()\n        .context(\"mountpoint must be canonical Unicode text\")?\n        .to_owned();\n    let registry: BTreeMap<String, registry::MountRecord> = registry::load_registry()?;\n    let Some(record) = registry.get(&key).cloned() else {\n        return Ok(());\n    };\n    let status = kernel_lease_status(client, &record.mount_id).await?;","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/main.rs#L771-L807","documentation":"The registry record's control_path must equal registry::control_path(&mount_id), the canonical derived path for that mount id. If the stored path differs, the record was created by a non-canonical writer, moved between systems, or hand-edited, and the provider refuses to trust it rather than talking to an arbitrary socket path.","triggerScenarios":"validate_record finds record.control_path != registry::control_path(record.mount_id) — registry file copied from another machine/user (different base temp dir), an older provider version that used a different path scheme, or manual registry edits.","commonSituations":"Sharing or migrating the registry file between users/hosts where XDG runtime dirs differ; upgrading the provider after a control-path scheme change; symlinks or relative paths stored instead of canonical absolute paths.","solutions":["Regenerate the registry entry: remove the record and re-mount so control_path is recomputed canonically","If a version change altered the path scheme, clear the old registry and remount all mounts with the new provider","Ensure the registry is not shared across users/hosts; keep it under the per-user runtime directory","Stop hand-editing control_path; always let the provider derive it from mount_id"],"exampleFix":"// before\n\"control_path\": \"/tmp/my-custom-sock.sock\"   // hand-edited\n// after: derived canonically from mount_id\n\"control_path\": \"/run/user/1000/astrid-fuse/control/<mount-id>.sock\"","handlingStrategy":"validation","validationCode":"// Verify the record's control path is canonical before trusting it\nlet expected = registry::control_path(&record.mount_id)?;\nif record.control_path != expected {\n    return Err(anyhow!(\"non-canonical control path {} (expected {})\", record.control_path.display(), expected.display()));\n}","typeGuard":"fn has_canonical_control_path(record: &MountRecord) -> bool {\n    registry::control_path(&record.mount_id).map(|c| c == record.control_path).unwrap_or(false)\n}","tryCatchPattern":"match validate_record(&record, &status) {\n    Err(e) if e.to_string().contains(\"control path is not canonical\") => {\n        // record from an old scheme or foreign host: purge and remount\n        registry::remove_record(&record.mount_id)?;\n        remount_fresh(client, &acting_principal, &record.mountpoint).await?;\n    }\n    other => other,\n}","preventionTips":["Always derive control_path via registry::control_path(mount_id); never store ad-hoc paths","Do not copy the registry file between users or hosts — runtime dirs differ per machine/user","After a control-path scheme change in the provider, clear the registry and remount everything","Store absolute canonical paths only (no symlinks or relative segments)"],"tags":["registry","validation","path","storage"],"backgroundTag":"invalid-argument-format","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}