diff --git a/servers/Azure.Mcp.Server/changelog-entries/yunliu1-azapi-get-bad-request.yaml b/servers/Azure.Mcp.Server/changelog-entries/yunliu1-azapi-get-bad-request.yaml new file mode 100644 index 0000000000..fe8afd1721 --- /dev/null +++ b/servers/Azure.Mcp.Server/changelog-entries/yunliu1-azapi-get-bad-request.yaml @@ -0,0 +1,3 @@ +changes: + - section: "Bugs Fixed" + description: "Fixed `azureterraform_azapi_get` returning `500 InternalServerError` for invalid resource type or API version inputs. The tool now returns `400 BadRequest` with an actionable message, enabling agents to auto-correct and retry with valid inputs." diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs index 04b416f5a3..0368b092a7 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System.IO; using System.Net; using Azure.Mcp.Tools.AzureTerraform.Models; using Azure.Mcp.Tools.AzureTerraform.Options; @@ -55,6 +56,12 @@ protected override AzApiDocsOptions BindOptions(ParseResult parseResult) }; } + protected override HttpStatusCode GetStatusCode(Exception ex) => ex switch + { + InvalidDataException => HttpStatusCode.BadRequest, + _ => base.GetStatusCode(ex) + }; + public override async Task ExecuteAsync( CommandContext context, ParseResult parseResult, diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.Tests/AzApiDocsGetCommandTests.cs b/tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.Tests/AzApiDocsGetCommandTests.cs index cdb65e5222..ae05690efd 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.Tests/AzApiDocsGetCommandTests.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.Tests/AzApiDocsGetCommandTests.cs @@ -136,7 +136,7 @@ public async Task ExecuteAsync_ServiceThrows_HandlesException() var response = await ExecuteCommandAsync("--resource-type", "Microsoft.Fake/nonexistent"); - Assert.NotEqual(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.BadRequest, response.Status); } [Theory] diff --git a/tools/Azure.Mcp.Tools.BicepSchema/src/Services/ResourceProperties/ResourceVisitor.cs b/tools/Azure.Mcp.Tools.BicepSchema/src/Services/ResourceProperties/ResourceVisitor.cs index e31b5a63ac..1471eab722 100644 --- a/tools/Azure.Mcp.Tools.BicepSchema/src/Services/ResourceProperties/ResourceVisitor.cs +++ b/tools/Azure.Mcp.Tools.BicepSchema/src/Services/ResourceProperties/ResourceVisitor.cs @@ -86,12 +86,13 @@ public string[] GetResourceApiVersions(string resourceTypeName) { (string providerName, _, _) = ResourceParser.ParseResourceType(resourceTypeName); - if (!GetAllResourceTypesAndVersionsByProvider().TryGetValue(providerName, out ProviderResourceTypes? provider)) + if (!GetAllResourceTypesAndVersionsByProvider().TryGetValue(providerName, out ProviderResourceTypes? provider) + || !provider.ResourceTypes.TryGetValue(resourceTypeName.ToLowerInvariant(), out UniqueResourceType? uniqueResourceType)) { - throw new Exception($"Resource type {resourceTypeName} not found."); + throw new InvalidDataException($"Resource type {resourceTypeName} not found."); } - return [.. provider.ResourceTypes[resourceTypeName.ToLowerInvariant()].ApiVersions]; + return [.. uniqueResourceType.ApiVersions]; } public TypesDefinitionResult LoadSingleResource(string resourceTypeName, string apiVersion) diff --git a/tools/Azure.Mcp.Tools.BicepSchema/tests/Azure.Mcp.Tools.BicepSchema.Tests/GetSchemaTests.cs b/tools/Azure.Mcp.Tools.BicepSchema/tests/Azure.Mcp.Tools.BicepSchema.Tests/GetSchemaTests.cs index 2a9188f864..67f467bb21 100644 --- a/tools/Azure.Mcp.Tools.BicepSchema/tests/Azure.Mcp.Tools.BicepSchema.Tests/GetSchemaTests.cs +++ b/tools/Azure.Mcp.Tools.BicepSchema/tests/Azure.Mcp.Tools.BicepSchema.Tests/GetSchemaTests.cs @@ -33,7 +33,7 @@ public void GetResourcePropertySchema_ShouldThrowOnNotFound() SchemaGenerator.ConfigureServices(serviceCollection); IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); - var exception = Assert.Throws(() => + var exception = Assert.Throws(() => { TypesDefinitionResult result = SchemaGenerator.GetResourceTypeDefinitions(serviceProvider, "Microsoft.Unknown/virtualRandom"); _ = SchemaGenerator.GetResponse(result);