{"record":{"id":"0ef170bdef60fd43","repo":"nopSolutions/nopCommerce","slug":"video-cannot-be-loaded","errorCode":null,"errorMessage":"Video cannot be loaded","messagePattern":"Video cannot be loaded","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Presentation/Nop.Web/Areas/Admin/Factories/ProductModelFactory.cs","lineNumber":1630,"sourceCode":"    public virtual async Task<ProductVideoListModel> PrepareProductVideoListModelAsync(ProductVideoSearchModel searchModel, Product product)\n    {\n        ArgumentNullException.ThrowIfNull(searchModel);\n        ArgumentNullException.ThrowIfNull(product);\n\n        //get product videos\n        var productVideos = (await _productService.GetProductVideosByProductIdAsync(product.Id)).ToPagedList(searchModel);\n\n        //prepare grid model\n        var model = await new ProductVideoListModel().PrepareToGridAsync(searchModel, productVideos, () =>\n        {\n            return productVideos.SelectAwait(async productVideo =>\n            {\n                //fill in model values from the entity\n                var productVideoModel = productVideo.ToModel<ProductVideoModel>();\n\n                //fill in additional values (not existing in the entity)\n                var video = (await _videoService.GetVideoByIdAsync(productVideo.VideoId))\n                    ?? throw new Exception(\"Video cannot be loaded\");\n\n                productVideoModel.VideoUrl = video.VideoUrl;\n\n                return productVideoModel;\n            });\n        });\n\n        return model;\n    }\n\n    /// <summary>\n    /// Prepare paged product specification attribute list model\n    /// </summary>\n    /// <param name=\"searchModel\">Product specification attribute search model</param>\n    /// <param name=\"product\">Product</param>\n    /// <returns>\n    /// A task that represents the asynchronous operation\n    /// The task result contains the product specification attribute list model","sourceCodeStart":1612,"sourceCodeEnd":1648,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Areas/Admin/Factories/ProductModelFactory.cs#L1612-L1648","documentation":"Thrown while preparing the admin product-video grid (PrepareProductVideoListModel). For each ProductVideo mapping row the factory loads the Video via _videoService.GetVideoByIdAsync(productVideo.VideoId); if null, it throws a bare System.Exception that propagates. It indicates the ProductVideoMapping join references a VideoId with no corresponding Video record. Same structural defect as the picture variant: an orphaned mapping row.","triggerScenarios":"A ProductVideoMapping row has a VideoId for which VideoService.GetVideoByIdAsync returns null. Caused by a video record deleted while its product mapping remained, or a failed video ingestion that left a dangling mapping.","commonSituations":"Video record hard-deleted from DB without removing ProductVideoMapping; failed upload leaving orphan mapping; storage/backend migration dropping video entries; video plugin uninstall removing Video rows but not mappings.","solutions":["Remove or repair the orphaned ProductVideoMapping rows whose VideoId lacks a Video record.","Re-upload the missing video and re-attach it to the product.","Integrity check: SELECT * FROM Product_Video_Mapping pvm LEFT JOIN Video v ON v.Id = pvm.VideoId WHERE v.Id IS NULL; delete those rows.","Restore the Video table from backup if several are missing."],"exampleFix":"// before\nvar video = (await _videoService.GetVideoByIdAsync(productVideo.VideoId))\n    ?? throw new Exception(\"Video cannot be loaded\");\n// after (skip broken row)\nvar video = await _videoService.GetVideoByIdAsync(productVideo.VideoId);\nif (video is null)\n{\n    await _logger.WarningAsync($\"ProductVideo mapping {productVideo.Id} references missing video {productVideo.VideoId}\");\n    return null;\n}","handlingStrategy":"validation","validationCode":"// Confirm each video mapping resolves before building the grid.\nvar productVideos = await _productService.GetProductVideosByProductIdAsync(product.Id);\nvar orphans = productVideos.Where(pv => (await _videoService.GetVideoByIdAsync(pv.VideoId)) is null).ToList();\nif (orphans.Any())\n    await _logger.WarningAsync($\"{orphans.Count} product-video mappings reference missing videos.\");","typeGuard":"static bool VideoResolved(Video v) => v is not null;","tryCatchPattern":"try { /* PrepareToGridAsync body */ }\ncatch (Exception ex) when (ex.Message == \"Video cannot be loaded\")\n{\n    await _logger.WarningAsync(ex.Message, ex);\n    /* return empty/partial grid */\n}","preventionTips":["Remove ProductVideoMapping rows when deleting a Video record.","Integrity-check Product_Video_Mapping against Video and prune orphans.","Handle failed video uploads atomically so no mapping row is left without a video."],"tags":["nopcommerce","admin","product","video","orphan-reference","data-integrity"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}