{"record":{"id":"84d40f49eb7af268","repo":"microsoft/aspire","slug":"image-must-be-a-string-or-addcontaineroptions","errorCode":null,"errorMessage":"Image must be a string or AddContainerOptions.","messagePattern":"Image must be a string or AddContainerOptions\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs","lineNumber":165,"sourceCode":"    /// <param name=\"name\">The name of the resource.</param>\n    /// <param name=\"image\">The image name or image options for the container.</param>\n    /// <returns>The <see cref=\"IResourceBuilder{T}\"/> for chaining.</returns>\n    /// <ats-returns>The resource builder.</ats-returns>\n    [AspireExport(\"addContainer\")]\n    internal static IResourceBuilder<ContainerResource> AddContainerForPolyglot(\n        this IDistributedApplicationBuilder builder,\n        [ResourceName] string name,\n        [AspireUnion(typeof(string), typeof(AddContainerOptions))] object image)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n        ArgumentException.ThrowIfNullOrEmpty(name);\n        ArgumentNullException.ThrowIfNull(image);\n\n        return image switch\n        {\n            string imageName => AddContainer(builder, name, imageName),\n            AddContainerOptions options => AddContainer(builder, name, options),\n            _ => throw new ArgumentException(\"Image must be a string or AddContainerOptions.\", nameof(image))\n        };\n    }\n\n    private static IResourceBuilder<ContainerResource> AddContainer(\n        IDistributedApplicationBuilder builder,\n        string name,\n        AddContainerOptions options)\n    {\n        ArgumentNullException.ThrowIfNull(options);\n        ArgumentException.ThrowIfNullOrEmpty(options.Image);\n\n        if (options.Tag is { } tag)\n        {\n            ArgumentException.ThrowIfNullOrEmpty(tag);\n            return AddContainer(builder, name, options.Image, tag);\n        }\n\n        return AddContainer(builder, name, options.Image);","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs#L147-L183","documentation":"AddContainerForPolyglot accepts the image argument as either a plain string (image name/reference) or an AddContainerOptions object. This ArgumentException is thrown for any other argument type, or an unsupported null/other value after the null check.","triggerScenarios":"Calling AddContainerForPolyglot with an image argument that is neither string nor AddContainerOptions (e.g. an integer, object, or unhandled type from dynamic/polyglot code).","commonSituations":"Polyglot apphosts passing loosely typed image values; code generators emitting the wrong type; JS/Python wrappers marshalling the image argument incorrectly.","solutions":["Pass the image as a string such as \"docker.io/library/redis:latest\".","Alternatively construct and pass an AddContainerOptions instance.","Check the dynamic language binding so the argument is marshalled as string or AddContainerOptions, not an unmapped type.","exampleFix placeholder"],"exampleFix":"// before\nbuilder.AddContainerForPolyglot(\"cache\", 42);\n// after\nbuilder.AddContainerForPolyglot(\"cache\", \"docker.io/library/redis:latest\");","handlingStrategy":"type-guard","validationCode":"if (image is not (string or AddContainerOptions))\n    throw new ArgumentException(\"Image must be a string or AddContainerOptions.\", nameof(image));","typeGuard":"bool IsValidImageArg(object? image) => image is string or AddContainerOptions;","tryCatchPattern":"try\n{\n    builder.AddContainerForPolyglot(name, image);\n}\ncatch (ArgumentException ex)\n{\n    // Coerce image to string or AddContainerOptions and retry\n}","preventionTips":["Always pass image names as strings in polyglot apphosts.","Use AddContainerOptions when extra configuration is needed.","Check the language binding's type marshalling for the image argument."],"tags":["container","arguments","polyglot","aspire"],"backgroundTag":"invalid-argument","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}