{"record":{"id":"ba41d844b38820a6","repo":"ClementTsang/bottom","slug":"error-while-iterating-over-volumes-err","errorCode":null,"errorMessage":"Error while iterating over volumes: {err:?}","messagePattern":"Error while iterating over volumes: (.+?)","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/collection/disks/windows/bindings.rs","lineNumber":143,"sourceCode":"        let volume = current_volume(&buffer);\n        ret.push(volume_io(&volume).map(|res| (res, volume.to_string_lossy().to_string())));\n    }\n\n    // Now iterate until there are no more volumes.\n    while unsafe { FindNextVolumeW(handle, &mut buffer) }.is_ok() {\n        let volume = current_volume(&buffer);\n        ret.push(volume_io(&volume).map(|res| (res, volume.to_string_lossy().to_string())));\n    }\n\n    let err = io::Error::last_os_error();\n    match err.raw_os_error() {\n        Some(ERROR_NO_MORE_FILES) => {\n            // Iteration completed successfully, continue on.\n        }\n        _ => {\n            // Some error occurred.\n            close_find_handle(handle)?;\n            bail!(\"Error while iterating over volumes: {err:?}\");\n        }\n    }\n\n    close_find_handle(handle)?;\n\n    Ok(ret)\n}\n\n/// Returns the volume name from a mount name if possible.\npub(crate) fn volume_name_from_mount(mount: &str) -> anyhow::Result<String> {\n    // According to winapi docs 50 is a reasonable length to accommodate the\n    // volume path https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumenameforvolumemountpointw\n    const VOLUME_MAX_LEN: usize = 50;\n\n    let mount = {\n        let mount_path = Path::new(mount);\n        let mut wide_path = mount_path.as_os_str().encode_wide().collect::<Vec<_>>();\n","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/ClementTsang/bottom/blob/b77d3175028849824e987c35177e8f61450d72e7/src/collection/disks/windows/bindings.rs#L125-L161","documentation":"While walking volumes with FindNextVolumeW in all_volume_io, the last OS error was neither success nor ERROR_NO_MORE_FILES, so the library closes the find handle and bails with the iteration error. ERROR_NO_MORE_FILES is the normal loop-exit condition; any other code means enumeration genuinely failed midway. Results gathered so far are discarded.","triggerScenarios":"FindNextVolumeW stops succeeding and last_os_error is not ERROR_NO_MORE_FILES — e.g. ERROR_MORE_DATA if a volume path exceeds MAX_PATH, handle invalidated mid-iteration, or the mount point database changed while iterating (volume added/removed).","commonSituations":"Systems with very long volume GUID paths exceeding the MAX_PATH buffer; hot-plugging or unmounting drives during a scan; corrupted mount manager state mid-enumeration.","solutions":["Inspect the wrapped err's Win32 code; ERROR_MORE_DATA means the path buffer (MAX_PATH u16s) is too small — use a larger buffer","Retry the full enumeration; transient races from volumes appearing/disappearing resolve on a second pass","Return the partially collected results with a warning instead of bailing","Check disk/storage health — persistent non-NO_MORE_FILES codes can indicate mount manager corruption (chkdsk / mountvol checks)"],"exampleFix":"// before\nmatch err.raw_os_error() {\n    Some(ERROR_NO_MORE_FILES) => {}\n    _ => {\n        close_find_handle(handle)?;\n        bail!(\"Error while iterating over volumes: {err:?}\");\n    }\n}\n// after\nmatch err.raw_os_error() {\n    Some(ERROR_NO_MORE_FILES) => {}\n    _ => {\n        let _ = close_find_handle(handle);\n        eprintln!(\"partial volume enumeration: {err:?}\"); // keep partial results\n    }\n}","handlingStrategy":"retry","validationCode":"// use a buffer larger than MAX_PATH to survive long volume GUID paths\nlet mut buffer = [0u16; 128]; // > MAX_PATH (260 bytes / 50 chars GUID path is fine, but be generous)\n","typeGuard":null,"tryCatchPattern":"match all_volume_io() {\n    Ok(r) => r,\n    Err(e) => {\n        log::warn!(\"volume iteration failed, retrying once: {e:?}\");\n        all_volume_io().unwrap_or_default()\n    }\n}","preventionTips":["Allocate a generous buffer for volume GUID paths instead of bare MAX_PATH","Avoid adding/removing drives during a scan","Treat enumeration errors as transient and retry once"],"tags":["windows","win32","volumes","iteration"],"backgroundTag":"api-error-response","analyzedSha":"b77d3175028849824e987c35177e8f61450d72e7","analyzedAt":"2026-09-07T14:53:21.246Z","contentChangedAt":"2026-09-07T14:53:21.246Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}