fix(conformance): send empty path labels like omitted ones; route53/lambda to 100%
Summary
Part of restoring true 100% Smithy conformance (main's CI probe is at 256,922/257,391; the baseline check only fails a service that drops >100 below its recorded count, so these were hidden).
Probe: empty path labels. For negative_too_short_<label> with min=1, the probe sent an empty label (e.g. GET /2015-03-31/functions/, GET /2013-04-01/queryloggingconfig/). No SDK can send that (smithy-rs refuses empty labels), and the URL is byte-identical to the List op with a trailing slash, which AWS serves as a list (#1645). An empty label is now sent like an omitted one: the {Name} placeholder for model-built paths, and a pattern-invalid sentinel for Lambda's legacy path (a valid-looking sentinel creates layers / is an idempotent delete). S3 keeps sending its empty Key (a sentinel key would be a valid object key). The variant still sends a real request and is judged on the response.
Before/after on all 43 REST probe services (main binaries vs branch binaries, fresh server each): no service lost a passing variant and no service's total changed.
| service | main | branch |
|---|---|---|
| bedrock | 4029/4044 | 4044/4044 |
| cloudfront | 4110/4112 | 4112/4112 |
| lambda | 3941/3949 | 3949/3949 |
| route53 | 2381/2394 | 2394/2394 |
| other 39 | unchanged |
Route53. The router dropped every empty segment, so a request with an empty id matched no route and returned an undeclared 404 InvalidArgument (9 ops). It now routes on the raw path: keep interior empty segments and trim a trailing slash; then keep the trailing empty segment; then fall back to the old behaviour. GET /hostedzone/ still lists; DELETE /hostedzone/ returns NoSuchHostedZone; /hostedzone//rrset no longer routes to GetHostedZone("rrset").
Lambda. LayerName is validated (140 chars, the model's pattern, bare name or layer ARN) on all seven layer ops, and CallbackId against its base64 pattern on the three durable-execution callback ops, returning ValidationException with the AWS "1 validation error detected" wording (added to Lambda's service_common_errors, as these are API-level constraint errors the model does not declare per op).
Conformance seed. The GetFunctionConcurrency documented example assumes 250 reserved concurrency (and the DeleteFunctionConcurrency example clears it), so the probe seeds it only around that op and restores the previous value through a drop guard.
Cross-account Lambda layer access via layer ARNs is handled separately. The baseline is re-recorded for every service at once in a final PR.
Test plan
- Unit: route53 router (3), layer name + callback id validation, probe empty-label handling (incl. S3 unchanged), seed guard (3, incl. restore on panic).
- E2E:
empty_id_label_reaches_its_operation(route53, raw HTTP),malformed_layer_name_is_rejected_by_every_layer_op,durable_execution_callback_id_must_match_its_pattern; route53, lambda_layers, lambda_regional, lambda_persistence, host_routing and CloudFormation lambda/route53 suites pass locally. Docker-dependent Lambda invoke tests ran in CI only (no Docker locally). - Conformance tests: route53 (5 files), lambda.
- Probe table above.
Summary by cubic
Brings route53 and lambda Smithy conformance to 100% by fixing how empty path labels are probed and routed, and adding Lambda input validation that was missing. No other service lost a passing variant.
- Empty
@httpLabelvalues are now sent like omitted ones: no SDK can serialize an empty label, and the URL collapses into the List operation's trailing-slash form. S3 still sends its emptyKey. - Route 53 routes on the raw wire path, keeping interior empty segments, so an empty ID reaches its operation instead of returning an undeclared 404
InvalidArgument;GET /hostedzone/still lists. LayerName(bare name or layer ARN, max 140 chars) andCallbackId(base64 pattern) are validated across all layer and durable-execution callback operations, returningValidationExceptionwith AWS's "1 validation error detected" wording. Layer ARNs minted for fakecloud's own region and account are exempt from the ARN pattern, since--region localor a non-AWS--account-idwouldn't match AWS's shape.- The probe seeds
my-function's reserved concurrency to 250 only aroundGetFunctionConcurrency, whose documented example assumes it, and restores the previous value with a drop guard that survives panics.