{"record":{"id":"e25a76c2fb97807c","repo":"Unity-Technologies/UnityCsReference","slug":"fileutil-openread-invalid-uds-hash-in-path-path","errorCode":null,"errorMessage":"FileUtil.OpenRead: Invalid UDS hash in path '{path}'","messagePattern":"FileUtil\\.OpenRead: Invalid UDS hash in path '(.+?)'","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/FileUtil.cs","lineNumber":51,"sourceCode":"                // materialise the data through the native VFS read\n                byte[] data = ReadAllBytesInternal(path);\n                return new MemoryStream(data, writable: false);\n            }\n\n            // The 'physical' path for a VirtualArtifact will be a UDS virtual path\n            if (physicalPath.StartsWith(k_UdsPathPrefix, StringComparison.Ordinal))\n                return OpenReadUDS(physicalPath);\n\n            // Fall back to opening the physical file in the normal way\n            return File.Open(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);\n        }\n\n        static Stream OpenReadUDS(string path)\n        {\n            string hashStr = path[(path.LastIndexOf('/') + 1)..];\n            var hash = Hash128.Parse(hashStr);\n            if (!hash.isValid)\n                throw new IOException($\"FileUtil.OpenRead: Invalid UDS hash in path '{path}'\");\n\n            IntPtr handle = UDS.Acquire(hash);\n            if (handle == IntPtr.Zero)\n                throw new IOException($\"FileUtil.OpenRead: Failed to acquire UDS content for '{path}'\");\n\n            return new UDSReadStream(handle);\n        }\n\n        public static byte[] ReadAllBytes(string path)\n        {\n            if (string.IsNullOrEmpty(path))\n                throw new ArgumentException(\"Path cannot be null or empty.\", nameof(path));\n\n            return ReadAllBytesInternal(path);\n        }\n\n        public static string ReadAllText(string path)\n        {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/FileUtil.cs#L33-L69","documentation":"OpenReadUDS extracts the trailing path segment as a Hash128 string and parses it; if Hash128.Parse yields an invalid hash, the path was not a well-formed UDS (Unity Data Storage) content path and the method throws IOException. This guards the native UDS.Acquire call from receiving garbage.","triggerScenarios":"A path with the uds:/ prefix whose final segment is not a 32-character hex Hash128 — e.g. truncated, corrupted, manually edited, or a path that looks like UDS but is actually a different virtual scheme.","commonSituations":"Serialised UDS paths that were truncated by length limits. Manually constructed virtual paths. Logging/transport layers that mangle the path. A version change in the UDS path format.","solutions":["Validate the trailing segment with Hash128.Parse before calling OpenRead, or assert the path shape (uds:/<32-hex>).","Do not hand-construct UDS paths; obtain them from the API that owns the virtual artefact.","If paths come from persistence, validate length/format on load and discard malformed entries."],"exampleFix":"// before\nusing Stream s = FileUtil.OpenRead(udsPath);\n// after\nstring hashStr = udsPath[(udsPath.LastIndexOf('/') + 1)..];\nif (!Hash128.Parse(hashStr).isValid) throw new ArgumentException(\"malformed UDS path\");\nusing Stream s = FileUtil.OpenRead(udsPath);","handlingStrategy":"validation","validationCode":"string hashStr = path[(path.LastIndexOf('/') + 1)..];\nif (!Hash128.Parse(hashStr).isValid)\n    throw new ArgumentException(\"malformed UDS path\", nameof(path));\nusing Stream s = FileUtil.OpenRead(path);","typeGuard":"static bool IsWellFormedUdsPath(string p) =>\n    p != null && p.StartsWith(\"uds:/\") && Hash128.Parse(p[(p.LastIndexOf('/') + 1)..]).isValid;","tryCatchPattern":null,"preventionTips":["Never hand-construct UDS paths; obtain them from the API that owns the virtual artefact.","Validate the trailing hash with Hash128.Parse before opening.","On load, discard any persisted UDS path whose shape fails validation."],"tags":["filesystem","uds","hash","validation","unity-editor"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}