Description
When a Smithy operation has a @required @httpQuery parameter, the generated SSDK throws UnknownOperationException instead of ValidationException when the parameter is missing from the request.
Expected Behavior
A request missing a required query parameter should return a ValidationException with details about the missing field.
Actual Behavior
The request fails to match any operation in HttpBindingMux, resulting in UnknownOperationException with message: "request did not match the expected service operation".
Root Cause
The HttpBindingMux uses required query parameters as part of operation routing/matching, not just validation. In UriSpec.match():
for (const querySegment of this.querySegments) {
if (!(querySegment.key in req.query)) {
return false; // Routing fails here
}
}
This means the mux cannot distinguish between:
- A genuinely unknown operation
- A known operation with missing required query parameters
Deeper Issue: Query Params Used for Routing Instead of Validation
The SSDK generates both:
- Per-operation handlers (e.g.,
GetResourceHandler) - one Lambda per operation
- Monolithic service handler (
MyServiceHandler) - single Lambda for all operations
In both cases, the mux includes required query params for routing:
// Monolithic handler mux - routes between operations
const mux = new HttpBindingMux([
new UriSpec('GET',
[{ type: 'path_literal', value: "item" }],
[{ type: 'query', key: "id" }], // Used for routing!
{ operation: "GetItem" }
),
new UriSpec('PUT',
[{ type: 'path_literal', value: "item" }],
[],
{ operation: "UpdateItem" }
),
]);
The mux legitimately needs to distinguish operations on the same path with different methods. But using required query params for this distinction is wrong - they should be validated after routing, not used for routing.
Meanwhile, the SSDK does generate proper validation for required query params:
case "id": {
memberValidators["id"] = new CompositeValidator([
new RequiredValidator(),
]);
break;
}
But this validation runs after the mux, so it never executes when the query param is missing.
Reproduction
Smithy model:
@http(method: "GET", uri: "/resource")
@readonly
operation GetResource {
input: GetResourceInput
}
structure GetResourceInput {
@required
@httpQuery("id")
id: String
}
Request:
Expected response:
{
"__type": "ValidationException",
...
}
Actual response:
{
"__type": "UnknownOperationException",
...
}
Suggested Fix
The mux should only use path and method for routing. Required query params should be handled by validation, not routing. Options:
- Don't include
@required @httpQuery params in mux querySegments - only use query params for routing when they disambiguate operations (e.g., @httpQueryParams with literal values)
- Two-pass matching - match on path/method first, then return partial match info for missing query params so the handler can throw
ValidationException
Environment
@aws-smithy/server-common
- TypeScript SSDK
Description
When a Smithy operation has a
@required@httpQueryparameter, the generated SSDK throwsUnknownOperationExceptioninstead ofValidationExceptionwhen the parameter is missing from the request.Expected Behavior
A request missing a required query parameter should return a
ValidationExceptionwith details about the missing field.Actual Behavior
The request fails to match any operation in
HttpBindingMux, resulting inUnknownOperationExceptionwith message: "request did not match the expected service operation".Root Cause
The
HttpBindingMuxuses required query parameters as part of operation routing/matching, not just validation. InUriSpec.match():This means the mux cannot distinguish between:
Deeper Issue: Query Params Used for Routing Instead of Validation
The SSDK generates both:
GetResourceHandler) - one Lambda per operationMyServiceHandler) - single Lambda for all operationsIn both cases, the mux includes required query params for routing:
The mux legitimately needs to distinguish operations on the same path with different methods. But using required query params for this distinction is wrong - they should be validated after routing, not used for routing.
Meanwhile, the SSDK does generate proper validation for required query params:
But this validation runs after the mux, so it never executes when the query param is missing.
Reproduction
Smithy model:
Request:
Expected response:
{ "__type": "ValidationException", ... }Actual response:
{ "__type": "UnknownOperationException", ... }Suggested Fix
The mux should only use path and method for routing. Required query params should be handled by validation, not routing. Options:
@required@httpQueryparams in muxquerySegments- only use query params for routing when they disambiguate operations (e.g.,@httpQueryParamswith literal values)ValidationExceptionEnvironment
@aws-smithy/server-common