microsoft/ailab · error · DirectoryNotFoundException

Container does not exist

Error message

Container {folderId} does not exist

What it means

GetPredictionAsync reads a previously saved prediction (groups.json, original.png, etc.) from an Azure Blob container named after the folderId. It first checks whether the container exists and throws DirectoryNotFoundException('Container {folderId} does not exist') when it does not, since results for an unknown folder id cannot be fetched.

Solutions

  1. Verify the folderId corresponds to an existing container in the storage account (check with Azure Storage Explorer or az storage container list)
  2. Re-run the image analysis to generate results before calling GetPredictionAsync
  3. Confirm the service is pointed at the same storage account/connection string that saved the results
  4. Check container cleanup/lifecycle policies that may have deleted old prediction containers
  5. Validate the folderId from the request (no truncation/typos) before calling

Example fix

// before
var detail = await service.GetPredictionAsync(id);
// after
var container = cloudBlobClient.GetContainerReference(id);
if (!await container.ExistsAsync()) {
    throw new ApplicationException($"Prediction {id} not found or expired; run the analysis again");
}
var detail = await service.GetPredictionAsync(id);
Defensive patterns

Strategy: try-catch

Validate before calling

var container = cloudBlobClient.GetContainerReference(folderId);
if (!await container.ExistsAsync())
    throw new ApplicationException($"Prediction {folderId} not found or expired");

Try / catch

try
{
    var detail = await service.GetPredictionAsync(folderId);
}
catch (DirectoryNotFoundException ex)
{
    logger.LogWarning(ex, "Prediction container missing for {FolderId}", folderId);
    return NotFound($"Prediction {folderId} not found or expired; re-run the analysis.");
}

Prevention

When it happens

Trigger: Calling GetPredictionAsync(folderId) with a folderId for which no blob container was ever created — e.g. a stale id, a typo, or querying before the image-processing Run completed and saved the results.

Common situations: Sharing a prediction URL whose blob container was deleted or expired (storage lifecycle/cleanup rules); typos in the folder id taken from a URL; hitting the API before the Sketch2Code run finished writing results; using a different storage account than the one that stored the results.

Related errors


AI-assisted analysis of microsoft/ailab@89fe2fc620 (2026-09-13). Data as JSON: /api/errors/b97001f7314827a3. Report an issue: GitHub.

Appendix: source

Thrown at Sketch2Code/Sketch2Code.Core/Services/ObjectDetectionAppService.cs:268

            var permission = new BlobContainerPermissions();
            permission.PublicAccess = BlobContainerPublicAccessType.Blob;
            await theContainer.SetPermissionsAsync(permission);
            if (relativePath != rootContainerPath)
            {
                fileName = Path.Combine(relativePath, fileName);
            }
            var blob = theContainer.GetBlockBlobReference(fileName);
            await blob.UploadTextAsync(html);
        }
        public async Task<PredictionDetail> GetPredictionAsync(string folderId)
        {
            if (String.IsNullOrWhiteSpace(folderId))
                throw new ArgumentNullException("folderId");

            var blobContainer = _cloudBlobClient.GetContainerReference(folderId);
            bool exists = await blobContainer.ExistsAsync();
            if (!exists)
                throw new DirectoryNotFoundException($"Container {folderId} does not exist");

            var groupsBlob = blobContainer.GetBlockBlobReference("groups.json");

            var detail = new PredictionDetail();

            detail.OriginalImage = await this.GetFile(folderId, "original.png");
            detail.PredictionImage = await this.GetFile(folderId, "predicted.png");
            detail.PredictedObjects = await this.GetFile<IList<PredictedObject>>(folderId, "results.json");
            var groupBox = await this.GetFile<GroupBox>(folderId, "groups.json");
            detail.GroupBox = new List<GroupBox> { groupBox };

            return detail;
        }
        public async Task<IList<CloudBlobContainer>> GetPredictionsAsync()
        {
            return await Task.Run(() => _cloudBlobClient.ListContainers().Where(l => l.Name != "azure-webjobs-hosts")
                .OrderByDescending(c => c.Properties.LastModified).ToList());
        }

View on GitHub (pinned to 89fe2fc620)