{"record":{"id":"94b632cc15d6f492","repo":"files-community/Files","slug":"the-following-properties-failed-to-save-failedpr","errorCode":null,"errorMessage":"The following properties failed to save: {failedProperties}","messagePattern":"The following properties failed to save: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Files.App/ViewModels/Properties/Items/CombinedFileProperties.cs","lineNumber":124,"sourceCode":"\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (file.Properties is not null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tawait file.Properties.SavePropertiesAsync(newDict);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfailedProperties += $\"{file.Name}: {prop.Name}\\n\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!string.IsNullOrWhiteSpace(failedProperties))\n\t\t\t{\n\t\t\t\tthrow new Exception($\"The following properties failed to save: {failedProperties}\");\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task ClearPropertiesAsync()\n\t\t{\n\t\t\tvar failedProperties = new List<string>();\n\t\t\tvar files = new List<BaseStorageFile>();\n\t\t\tforeach (var item in List)\n\t\t\t{\n\t\t\t\tBaseStorageFile file = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileFromPathAsync(item.ItemPath));\n\n\t\t\t\tif (file is null)\n\t\t\t\t\treturn;\n\n\t\t\t\tfiles.Add(file);\n\t\t\t}\n\n\t\t\tforeach (var group in ViewModel.PropertySections)","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/files-community/Files/blob/68c68a58d4d6a5f7197e07c8fff85cfd4279c78b/src/Files.App/ViewModels/Properties/Items/CombinedFileProperties.cs#L106-L142","documentation":"A plain System.Exception thrown by CombinedFileProperties.SyncPropertyChangesAsync (line 124) after one or more calls to BaseStorageFile.Properties.SavePropertiesAsync threw during a multi-file property save. Each failure is appended to a string as \"filename: propertyname\" and the aggregated list is rethrown once, so a multi-select Apply reports every failure together. The original exception is swallowed by a bare catch{} (line 113-116), so the underlying HRESULT/exception type (UnauthorizedAccessException, FileNotFoundException, E_INVALIDARG, property-handler-not-registered, etc.) is lost — only the human-readable file:property list survives.","triggerScenarios":"User selects multiple files, edits a property in the Details/Properties pane, and applies; for at least one selected file the SavePropertiesAsync call at line 110 throws. Concrete causes: file is read-only or the user lacks write ACL; file is open/locked by another process; the property is not backed by the file's shell property handler (e.g. setting System.Photo.EXIF on a .txt); the supplied value violates the property's type or range; file lives on FAT32/exFAT/network share with no NTFS property store; cloud placeholder (OneDrive) not hydrated.","commonSituations":"Multi-selecting files of mixed types and setting a property only some support; files on SMB/network shares with restricted or absent property handlers; files owned by another user or in a protected directory; antivirus or indexer locking the file during write; editing properties on a file still being written by another app; setting read-only system properties that the UI allowed because IsReadOnly wasn't set.","solutions":["Make sure each target file is writable and not locked before applying: clear the read-only attribute, close the application holding the file, and confirm the user has write permission on the path.","Confirm the property is applicable to every selected file's type — the property list from RetrieveAndInitializePropertiesAsync is already filtered per extension, so only set properties that appear (non-read-only) for each file; do not assume a property valid for one file type applies to all in a mixed selection.","For network/cloud locations, hydrate placeholders (OneDrive) or copy the file locally before editing properties, since non-NTFS volumes often lack the property store.","Treat the reported file:property list as authoritative: it tells you exactly which (file, property) pairs failed — retry just those after fixing the per-file blocker rather than re-applying all.","Improve diagnostics by replacing the bare catch{} (line 113) with catch (Exception ex) that logs ex (HRESULT + type) alongside the file:property, so the swallowed root cause is recoverable."],"exampleFix":"// before\ntry\n{\n    if (file.Properties is not null)\n        await file.Properties.SavePropertiesAsync(newDict);\n}\ncatch\n{\n    failedProperties += $\"{file.Name}: {prop.Name}\\n\";\n}\n\n// after\ntry\n{\n    if (file.Properties is not null)\n        await file.Properties.SavePropertiesAsync(newDict);\n}\ncatch (Exception ex)\n{\n    App.Logger?.LogWarning(ex, \"SavePropertiesAsync failed for {File}.{Prop}\", file.Name, prop.Name);\n    failedProperties += $\"{file.Name}: {prop.Name}\\n\";\n}","handlingStrategy":"try-catch","validationCode":"// Per-file gate before SavePropertiesAsync in the multi-select save loop\nforeach (var file in files)\n{\n    if (file is null || file.Properties is null) continue;\n\n    var attrs = file.Attributes;\n    if (attrs.HasFlag(FileAttributes.ReadOnly)) { /* skip or prompt */ continue; }\n\n    // Skip properties not applicable to this file's type — only set those\n    // present (and non-read-only) in its own retrieved property list.\n}","typeGuard":null,"tryCatchPattern":"// Wrap SyncPropertyChangesAsync at the call site; parse the file:property list\ntry\n{\n    await combined.SyncPropertyChangesAsync();\n}\ncatch (Exception ex) when (ex.Message.StartsWith(\"The following properties failed to save:\"))\n{\n    // ex.Message contains \"filename: propertyname\" per line — surface to user,\n    // retry the unaffected subset, or fix per-file blockers.\n    await ShowPropertySaveFailuresAsync(ex.Message);\n}","preventionTips":["Clear read-only / confirm write ACL on selected files before opening the Properties pane.","Avoid mixing unrelated file types in a multi-select property edit — a property valid for one extension often is not backed for another.","For network/cloud files, hydrate or copy locally before editing properties.","Replace the bare catch{} at CombinedFileProperties.cs:113 with catch (Exception ex) that logs ex, so the swallowed HRESULT/type is recoverable for support."],"tags":["properties","save","storage","winrt","multi-select"],"backgroundTag":null,"analyzedSha":"68c68a58d4d6a5f7197e07c8fff85cfd4279c78b","analyzedAt":"2026-08-13T10:34:54.614Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}