{"record":{"id":"671212b7e256f8ea","repo":"rustdesk/rustdesk","slug":"failed-to-copy-custom-txt-from-to","errorCode":null,"errorMessage":"Failed to copy custom txt from {:?} to {:?}: {}","messagePattern":"Failed to copy custom txt from (.+?) to (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/platform/windows.rs","lineNumber":3855,"sourceCode":"\n        if metadata.is_symlink() {\n            allow_err!(remove_custom_client_staging_dir(&custom_client_staging_dir));\n            bail!(\n                \"custom.txt at {:?} is a symlink, refusing to stage for security reasons.\",\n                src_path\n            );\n        }\n\n        if metadata.is_file() {\n            if !custom_client_staging_dir.exists() {\n                if let Err(e) = std::fs::create_dir_all(custom_client_staging_dir) {\n                    bail!(\"Failed to create parent directory {:?} when staging custom client files: {}\", custom_client_staging_dir, e);\n                }\n            }\n            let dst_path = custom_client_staging_dir.join(\"custom.txt\");\n            if let Err(e) = std::fs::copy(&src_path, &dst_path) {\n                allow_err!(remove_custom_client_staging_dir(&custom_client_staging_dir));\n                bail!(\n                    \"Failed to copy custom txt from {:?} to {:?}: {}\",\n                    src_path,\n                    dst_path,\n                    e\n                );\n            }\n        } else {\n            log::warn!(\n                \"custom.txt at {:?} is not a regular file, skipping.\",\n                src_path\n            );\n        }\n    } else {\n        log::info!(\"No custom txt found to stage for update.\");\n    }\n\n    Ok(())\n}","sourceCodeStart":3837,"sourceCodeEnd":3873,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540/src/platform/windows.rs#L3837-L3873","documentation":"After creating the staging directory, the code copies the regular-file `custom.txt` with `std::fs::copy`. A failed copy aborts the update (with best-effort cleanup of the staging dir) and reports source, destination, and the underlying io::Error.","triggerScenarios":"`std::fs::copy(&src_path, &dst_path)` returns `Err` — destination locked by another process, disk full, permission denied on the staging dir, or source unreadable at copy time.","commonSituations":"Another RustDesk instance holding `custom.txt` open in the staging dir; full system drive; ACL changes after a previous elevated run; AV interference during the update window.","solutions":["Retry the update after closing other RustDesk processes","Free disk space if the io::Error indicates insufficient space","Fix permissions on the staging directory (may require elevated delete + retry)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if !src_path.is_file() { return; }\nif !dst_dir_is_writable(&staging_dir) { /* fix ACLs first */ }\nif free_disk_space(&staging_dir)? < src_len_plus_margin { /* free space first */ }","typeGuard":null,"tryCatchPattern":"match std::fs::copy(&src_path, &dst_path) {\n    Err(e) if e.kind() == std::io::ErrorKind::StorageFull => log::error!(\"disk full during staging\"),\n    Err(e) => log::warn!(\"copy failed ({e}); retry update\"),\n    Ok(_) => {}\n}","preventionTips":["Free disk space before running updates","Ensure no process holds custom.txt open in the staging dir","Run updates with permissions to write the staging directory"],"tags":["windows","filesystem","copy"],"backgroundTag":"file-write-failed","analyzedSha":"91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540","analyzedAt":"2026-09-10T19:53:44.083Z","contentChangedAt":"2026-09-10T19:53:44.083Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}