Skip to content

InvokeRestApi in MWAA always returns 400 Bad Request with URL mismatch #3057

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
2 tasks done
tj3828 opened this issue Apr 11, 2025 · 5 comments
Closed
2 tasks done

InvokeRestApi in MWAA always returns 400 Bad Request with URL mismatch #3057

tj3828 opened this issue Apr 11, 2025 · 5 comments
Labels
response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@tj3828
Copy link

tj3828 commented Apr 11, 2025

Acknowledgements

Describe the bug

When using InvokeRestApi with the AWS SDK for Go v2, I'm consistently getting a 400 Bad Request error. The request URL in the actual HTTP call appears to be different from what I specified in my code.

Expected Behavior

The request should be constructed with the URL I specified in my code, which would include the DAG name in the path.

Current Behavior

The API call always results in a 400 Bad Request error with the following error message:

Operation error MWAA: InvokeRestApi, https response error StatusCode: 400, RequestID: 1b18a890-64a9-4276-aac9-df42af19a2ae, deserialization failed, failed to decode response body, invalid character 'U' looking for beginning of value

Debug logs show that the actual request URL is:
Image

Reproduction Steps

result, err := mwaaClient.InvokeRestApi(context.TODO(), &mwaa.InvokeRestApiInput{
    Name: aws.String(mwaaEnvironmentName),
    Path: aws.String(fmt.Sprintf("/api/v1/dags/%s/dagRuns", dag)),
    Body: document.NewLazyDocument(payload),
    Method: types.RestApiMethodPost,
})

Possible Solution

No response

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2/service/mwaa v1.34.2

Compiler and Version used

1.23

Operating System and version

mac OS 15.3.2

@tj3828 tj3828 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 11, 2025
@Madrigal
Copy link
Contributor

Expected Behavior
The request should be constructed with the URL I specified in my code, which would include the DAG name in the path.

InvokeRestApi operation is made to construct that request on your behalf, so calling /restapi/xxx is the expected behavior. The idea is that AWS handles authorization and sessions on your behalf, so you can only specify what request you want to get executed.

If you want to manually call your workflow directly as you described, you'll need to get a web token, exchange it for a web session, and then use that to call your hosted workflow, as described here (this is using Python but the same idea applies here)

@Madrigal Madrigal added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 15, 2025
@tj3828
Copy link
Author

tj3828 commented Apr 17, 2025

@Madrigal
Thank you for clarifying the URL construction issue - that was my misunderstanding.

However, I'm still unable to determine the root cause of the error. Through debugging, I've discovered that the X-Amzn-Errortype is returning ValidationException. This suggests that authentication is working properly, but there seems to be an issue with the request Body format or values.
What's puzzling is that I'm only passing simple values in my request, as shown in the code example above. I've even tried commenting out the Body parameter entirely and executing the request, but I continue to receive the exact same error response.

Additionally, since the response.body fails to deserialize (as indicated by the "invalid character 'U'" error), I can't extract any helpful information from the error message itself.

func awsRestjson1_deserializeOpErrorInvokeRestApi(response *smithyhttp.Response, metadata *middleware.Metadata) error {
	var errorBuffer bytes.Buffer
	if _, err := io.Copy(&errorBuffer, response.Body); err != nil {
		return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)}
	}

Could you provide any insight into what might be causing this ValidationException or suggest additional debugging approaches I could try?

@Madrigal
Copy link
Contributor

Yes. This may be tricky to de-serialize by the SDKs since the format coming from the service may not be JSON if it's coming directly from the workflow.

You can use ClientLogMode to print what the exact response is coming down the wire, which will help you identify what's going wrong

cfg, err := config.LoadDefaultConfig(ctx,
	config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody),
)

@tj3828
Copy link
Author

tj3828 commented Apr 17, 2025

cfg, err := config.LoadDefaultConfig(ctx,
config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody),
)

Using ClientLogMode, I was able to see the error: Update your environment to use InvokeRestApi. Note: InvokeRestApi is only supported for Airflow version 2.2 and above. Although my MWAA version is 2.7.2, I've determined that this particular error is outside the scope of this issue and will follow up with an AWS support case instead.

Thanks for the quick feedback!🙏

@tj3828 tj3828 closed this as completed Apr 17, 2025
Copy link

This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

2 participants