{"record":{"id":"658936755d6f31a1","repo":"stride3d/stride","slug":"could-not-find-project-associated-to-asset-assetitem","errorCode":null,"errorMessage":"Could not find project associated to asset [{AssetItem}]","messagePattern":"Could not find project associated to asset \\[(.+?)\\]","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Assets.Presentation/ViewModel/ScriptSourceFileAssetViewModel.cs","lineNumber":257,"sourceCode":"\n        private void TrackDocument()\n        {\n            // Make sure the path is correct\n            AssetItem.UpdateSourceFolders();\n\n            // Capture full path before going in a Task (might be renamed in between)\n            var fullPath = AssetItem.FullPath.ToOSPath();\n\n            DocumentId = Task.Run(async () =>\n            {\n                // Find DocumentId\n                var strideAssets = await StrideAssetsViewModel.InstanceTask;\n                workspace = await strideAssets.Code.Workspace;\n\n                AssetItem.UpdateSourceFolders();\n                var sourceProject = ((SolutionProject)AssetItem.Package.Container).FullPath.ToOSPath();\n                if (sourceProject == null)\n                    throw new InvalidOperationException($\"Could not find project associated to asset [{AssetItem}]\");\n\n                // Wait for project to be loaded, but bounded: a project that never appears (e.g. one that\n                // isn't in the workspace) must not spin forever and freeze callers that block on DocumentId.\n                Project project = null;\n                for (var retries = 0; retries < 500; retries++)\n                {\n                    cancellationToken.Token.ThrowIfCancellationRequested();\n\n                    // Wait for project to be available (case-insensitive: MSBuild and SolutionProject paths may differ in casing)\n                    project = workspace.CurrentSolution.Projects.FirstOrDefault(x => string.Equals(x.FilePath, sourceProject, StringComparison.OrdinalIgnoreCase));\n                    if (project != null)\n                        break;\n                    await Task.Delay(10);\n                }\n\n                if (project == null)\n                {\n                    // Couldn't locate the project; leave the asset untracked rather than hang.","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Assets.Presentation/ViewModel/ScriptSourceFileAssetViewModel.cs#L239-L275","documentation":"ScriptSourceFileAssetViewModel.TrackDocument resolves the Roslyn Project for the asset's owning package so it can wait for the project to load (bounded retry loop). The container of the asset's package is cast to SolutionProject and its FullPath converted to an OS path; if that path is null the asset is not associated with any project in the solution, and an InvalidOperationException with the asset name is thrown.","triggerScenarios":"TrackDocument (called from Initialize and UpdateIsDeletedStatus) runs on an asset whose AssetItem.Package.Container is not a project with a valid FullPath — e.g. the package is a standalone/session package not referenced by any .csproj in the current solution.","commonSituations":"Opening a script-source asset whose parent package was loaded outside a solution, a solution that failed to load or was partially loaded, or an asset moved to a package without an associated project file.","solutions":["Ensure the asset lives in a package that is part of the currently loaded solution with a valid .csproj FullPath.","Reload the solution/game studio session so package containers are correctly bound to SolutionProject instances.","Check ((SolutionProject)AssetItem.Package.Container).FullPath before calling TrackDocument and skip or queue tracking when it is null."],"exampleFix":"// before\nvar sourceProject = ((SolutionProject)AssetItem.Package.Container).FullPath.ToOSPath();\n// after\nvar container = AssetItem.Package.Container as SolutionProject;\nif (container?.FullPath == null)\n    return; // asset not associated with a solution project; skip document tracking\nvar sourceProject = container.FullPath.ToOSPath();","handlingStrategy":"validation","validationCode":"var container = AssetItem.Package.Container as SolutionProject;\nif (container?.FullPath == null)\n{\n    // asset not tied to a solution project — do not call TrackDocument\n    return;\n}","typeGuard":"static bool HasSolutionProject(AssetItem item) =>\n    item?.Package?.Container is SolutionProject p && !string.IsNullOrEmpty(p.FullPath);","tryCatchPattern":"try\n{\n    await viewModel.TrackDocument();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Could not find project associated to asset\"))\n{\n    logger.Warning($\"Skipping document tracking: {ex.Message}\");\n}","preventionTips":["Only create script-source assets inside packages that belong to a loaded solution.","Verify the solution fully loaded before initializing script asset view models.","Null-check Package.Container as SolutionProject and FullPath before tracking.","Reload the solution if packages were loaded standalone or a load partially failed."],"tags":["csharp","stride-editor","roslyn","project-loading"],"backgroundTag":"resource-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}