{"record":{"id":"cda14ed70499be15","repo":"microsoft/aspire","slug":"manifest-entry-entry-relativepath-does-not-contain-enough","errorCode":null,"errorMessage":"Manifest entry '{entry.RelativePath}' does not contain enough information to compute a fingerprint.","messagePattern":"Manifest entry '(.+?)' does not contain enough information to compute a fingerprint\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs","lineNumber":248,"sourceCode":"\n    private static string GetEntryFingerprint(AppHostServerClosureManifestEntry entry)\n    {\n        if (entry.IsPackageBacked)\n        {\n            return $\"packages/{entry.RelativePath}|{entry.AssetType ?? \"runtime\"}|{entry.PackageId}|{entry.PackageVersion}|{entry.PathInPackage}|{entry.PackageSha512}|{entry.SourcePath}\";\n        }\n\n        return GetProjectEntryFingerprint(entry);\n    }\n\n    private static string GetProjectEntryFingerprint(AppHostServerClosureManifestEntry entry)\n    {\n        if (entry.FileContentHash is { Length: > 0 } fileContentHash)\n        {\n            return $\"libs/{entry.RelativePath}|file|{fileContentHash}\";\n        }\n\n        throw new InvalidOperationException($\"Manifest entry '{entry.RelativePath}' does not contain enough information to compute a fingerprint.\");\n    }\n\n    private static string ComputeTextHash(string value)\n    {\n        var hash = new XxHash3();\n        hash.Append(Encoding.UTF8.GetBytes(value));\n        return Convert.ToHexString(hash.GetCurrentHash()).ToLowerInvariant();\n    }\n\n    internal static string ComputeFileHash(string path, CancellationToken cancellationToken)\n    {\n        var hash = new XxHash3();\n        using var stream = File.OpenRead(path);\n        var buffer = new byte[81920];\n        int bytesRead;\n        while ((bytesRead = stream.Read(buffer)) > 0)\n        {\n            cancellationToken.ThrowIfCancellationRequested();","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs#L230-L266","documentation":"Thrown by AppHostServerClosureSnapshots.GetProjectEntryFingerprint when a manifest entry has neither a file content hash nor enough backing information to derive a fingerprint. Fingerprinting is how the snapshot detects changes; an entry lacking a FileContentHash would be indistinguishable from others, so the code fails instead of emitting a colliding fingerprint.","triggerScenarios":"Calling GetProjectEntryFingerprint (via GetEntryFingerprint) on a manifest entry whose FileContentHash is null or empty and which is not package-backed.","commonSituations":"Hand-edited or partially written manifest files, a manifest producer version that stopped emitting FileContentHash, or entries created programmatically without hashing their content.","solutions":["Regenerate the manifest with a version that computes FileContentHash for every entry","Ensure entries backed by real files go through the file-hash path before fingerprinting","Inspect the manifest JSON for entries missing the hash field and fix their producer","Add the content hash manually if constructing entries in code"],"exampleFix":"// before\nvar entry = new ManifestEntry { RelativePath = \"libs/foo.js\" };\n// after\nvar entry = new ManifestEntry { RelativePath = \"libs/foo.js\", FileContentHash = ComputeHash(path) };","handlingStrategy":"validation","validationCode":"var bad = manifest.Entries\n    .Where(e => string.IsNullOrEmpty(e.FileContentHash))\n    .ToList();\nif (bad.Count > 0)\n    throw new InvalidOperationException($\"Entries missing FileContentHash: {string.Join(\", \", bad.Select(e => e.RelativePath))}\");","typeGuard":"bool IsFingerprintable(ManifestEntry e) =>\n    e.FileContentHash is { Length: > 0 };","tryCatchPattern":"try\n{\n    var fp = GetEntryFingerprint(entry);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"fingerprint\"))\n{\n    logger.LogError(\"Manifest entry {Entry} lacks hash; regenerate manifest.\", entry.RelativePath);\n}","preventionTips":["Always populate FileContentHash when constructing manifest entries","Regenerate manifests with a current producer version","Validate manifest completeness before fingerprinting","Avoid hand-editing generated manifests"],"tags":["manifest","fingerprint","validation"],"backgroundTag":"missing-required-field-invalid-state","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}