{"record":{"id":"a0b38db5e6d139a1","repo":"microsoft/aspire","slug":"at-least-one-terminal-host-is-required","errorCode":null,"errorMessage":"At least one terminal host is required.","messagePattern":"At least one terminal host is required\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/TerminalAnnotation.cs","lineNumber":75,"sourceCode":"\n    /// <summary>\n    /// Populates <see cref=\"TerminalHosts\"/> exactly once. Called by the\n    /// <see cref=\"BeforeStartEvent\"/> subscriber installed by\n    /// <see cref=\"TerminalResourceBuilderExtensions.WithTerminal{T}(IResourceBuilder{T}, Action{TerminalOptions}?)\"/>.\n    /// </summary>\n    /// <exception cref=\"InvalidOperationException\">Thrown when called more than once.</exception>\n    internal void Initialize(IReadOnlyList<TerminalHostResource> terminalHosts)\n    {\n        ArgumentNullException.ThrowIfNull(terminalHosts);\n\n        if (IsInitialized)\n        {\n            throw new InvalidOperationException(\"TerminalAnnotation has already been initialized.\");\n        }\n\n        if (terminalHosts.Count == 0)\n        {\n            throw new ArgumentException(\"At least one terminal host is required.\", nameof(terminalHosts));\n        }\n\n        for (var i = 0; i < terminalHosts.Count; i++)\n        {\n            if (terminalHosts[i] is null)\n            {\n                throw new ArgumentException($\"Terminal host at index {i} is null.\", nameof(terminalHosts));\n            }\n        }\n\n        _terminalHosts = terminalHosts;\n        IsInitialized = true;\n    }\n}\n\n#pragma warning restore ASPIRETERMINAL001\n\n/// <summary>","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/TerminalAnnotation.cs#L57-L93","documentation":"TerminalAnnotation.Initialize requires a non-empty set of terminal hosts; an empty list produces ArgumentException 'At least one terminal host is required.' An annotation with no hosts has no meaning, so the library fails fast rather than creating a useless terminal annotation.","triggerScenarios":"Calling TerminalAnnotation.Initialize with an empty collection (e.g. a list filtered down to zero hosts, or default-initialized list never populated) — reached via MaterializeTerminalHostsAsync, AddSyntheticTerminalAnnotation, BuildModel, or CreateHarness when no TerminalHostResource was created.","commonSituations":"Custom publish/terminal tooling that computes terminal hosts conditionally and ends up with none; tests constructing the annotation before adding any hosts; misconfigured harness where terminal hosts failed to be added to the model.","solutions":["Ensure at least one TerminalHostResource exists before calling Initialize; add the terminal host(s) to the application model first.","Guard with a count check and skip creating the annotation entirely when there are no terminal hosts.","Debug why host creation returned empty (filters, conditions, or publish mode flags) if hosts were expected."],"exampleFix":"// before\nterminalAnnotation.Initialize(terminalHosts); // terminalHosts is empty\n\n// after\nif (terminalHosts.Count > 0)\n{\n    terminalAnnotation.Initialize(terminalHosts);\n}","handlingStrategy":"validation","validationCode":"if (terminalHosts is not { Count: > 0 })\n    return; // nothing to initialize","typeGuard":null,"tryCatchPattern":"try\n{\n    terminalAnnotation.Initialize(terminalHosts);\n}\ncatch (ArgumentException ex)\n{\n    logger.LogError(ex, \"No terminal hosts provided: {Message}\", ex.Message);\n}","preventionTips":["Verify terminal hosts were added to the application model before initializing the annotation.","Short-circuit annotation creation when the computed host list is empty.","Investigate empty host computation (filters, mode flags) if hosts were expected."],"tags":["argument-validation","empty-collection","app-model"],"backgroundTag":"empty-required-field","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"}