{"record":{"id":"ab280340e4c182f5","repo":"microsoft/aspire","slug":"foundry-cli-did-not-return-a-model-id-for-model-modelname","errorCode":null,"errorMessage":"Foundry CLI did not return a model ID for model '{modelName}'.","messagePattern":"Foundry CLI did not return a model ID for model '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Foundry/FoundryLocalService.cs","lineNumber":526,"sourceCode":"    private static async Task<string> GetModelIdAsync(string modelName, CancellationToken cancellationToken)\n    {\n        var daemonVerb = await GetDaemonVerbAsync(cancellationToken).ConfigureAwait(false);\n        var arguments = daemonVerb == \"server\"\n            ? new[] { \"model\", \"info\", modelName, \"--output\", \"json\" }\n            : new[] { \"model\", \"info\", modelName };\n        var output = await RunFoundryCommandAsync(arguments, onOutput: null, cancellationToken).ConfigureAwait(false);\n\n        if (daemonVerb == \"server\" && TryParseModelInfo(output, out var modernModelId, out _))\n        {\n            return modernModelId;\n        }\n\n        if (TryParseModelId(output, out var modelId))\n        {\n            return modelId;\n        }\n\n        throw new InvalidOperationException($\"Foundry CLI did not return a model ID for model '{modelName}'.\");\n    }\n\n    internal static bool TryParseEndpoint(string output, out Uri endpoint)\n    {\n        // Foundry CLI emits service startup lines like:\n        //   Service is Started on http://127.0.0.1:50920/, PID 78399!\n        // and status lines like:\n        //   Model management service is running on http://127.0.0.1:50920/openai/status\n        var match = s_urlRegex.Match(output);\n        if (!match.Success)\n        {\n            endpoint = null!;\n            return false;\n        }\n\n        var url = match.Value.TrimEnd(',', '.', '!', ')', ']', '}', '\"', '\\'');\n        if (!Uri.TryCreate(url, UriKind.Absolute, out var parsedEndpoint))\n        {","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Foundry/FoundryLocalService.cs#L508-L544","documentation":"GetModelIdAsync runs `foundry model info <modelName>` and attempts to parse a model ID from the output, first with the modern JSON shape (TryParseModelInfo when the daemon verb is 'server') and then with the legacy parser (TryParseModelId). If neither parser finds a model ID in the CLI's output, this InvalidOperationException is thrown — the CLI responded, but not in a shape the integration recognizes.","triggerScenarios":"DownloadModelAsync or legacyModelId path calls GetModelIdAsync; the command exits 0 (so no exit-code error) but the output contains no recognizable model ID — e.g. the model is not downloaded/known and the CLI prints a human-readable 'not found' or empty message instead of the expected JSON or ID line.","commonSituations":"Requesting a model that is not present locally or misspelling its name/alias; a Foundry CLI version whose `model info` output format differs from both supported shapes (modern JSON vs legacy text); the daemon verb detection picks the wrong parsing branch for the installed CLI.","solutions":["Run `foundry model info <modelName>` manually and compare its output to what the integration expects; confirm the exact model name via `foundry model list`.","Download/compile the model first (`foundry model download <modelName>`) so `model info` returns a real model ID.","Update the Foundry Local CLI to a version whose output matches the supported formats, then retry.","If your CLI version emits a new format, file an issue at microsoft/aspire with the raw `model info` output so the parser can be extended."],"exampleFix":"// before: alias that is not a downloaded model yields unparsable output\n.AddModel(\"phi-4-mini-q4-GS\", \"my-model\")\n\n// after: use an alias confirmed by `foundry model list` / `foundry model search`\n.AddModel(\"phi-4-mini\", \"my-model\")","handlingStrategy":"validation","validationCode":"// Verify the model resolves and info output is parseable before wiring it in:\n//   foundry model search <modelName>\n//   foundry model info <modelName> --output json   # must contain a model id field\nvar psi = new ProcessStartInfo(\"foundry\", $\"model info {modelName} --output json\") { RedirectStandardOutput = true, UseShellUse = false };\nusing var p = Process.Start(psi)!;\nvar output = await p.StandardOutput.ReadToEndAsync();\nbool hasModelId = output.Contains(\"id\", StringComparison.OrdinalIgnoreCase) || output.Contains(\"modelId\", StringComparison.OrdinalIgnoreCase);","typeGuard":null,"tryCatchPattern":"try\n{\n    await model.DownloadAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"did not return a model ID\"))\n{\n    logger.LogError(ex, \"Could not resolve model ID for '{Model}'. Verify the name via `foundry model list` and that the CLI output format is supported.\", modelName);\n}","preventionTips":["Always use model names/aliases confirmed by `foundry model list` or `foundry model search`.","Download the model (`foundry model download <name>`) before relying on `model info` to resolve an ID.","Keep the CLI on a version whose `model info` output matches the supported JSON/legacy formats.","If the raw output looks fine but still fails, capture it and file an issue so the parser can support the new format."],"tags":["foundry","cli","output-parsing","model-id"],"backgroundTag":"unexpected-response-shape","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"}