Skip to content

fix(conformance): send empty path labels like omitted ones; route53/lambda to 100% - #2724

Merged
vieiralucas merged 6 commits into
mainfrom
fix/conformance-route53-lambda
Oct 17, 2026
Merged

vieiralucas merged 6 commits into
mainfrom
fix/conformance-route53-lambda

Conversation

@vieiralucas

@vieiralucas vieiralucas commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

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 @httpLabel values 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 empty Key.
  • 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) and CallbackId (base64 pattern) are validated across all layer and durable-execution callback operations, returning ValidationException with 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 local or a non-AWS --account-id wouldn't match AWS's shape.
  • The probe seeds my-function's reserved concurrency to 250 only around GetFunctionConcurrency, whose documented example assumes it, and restores the previous value with a drop guard that survives panics.

Written for commit 6233f28. Summary will update on new commits.

View guided diff Turn on auto-fix

…ambda to 100%

- Probe: a too-short label of "" produces a URL no SDK can send
  (smithy-rs refuses empty labels) that is wire-identical to the List
  op with a trailing slash (#1645). Send it like an omitted label
  ({Name} placeholder for model-built paths; for lambda's legacy path a
  pattern-invalid sentinel). S3 keeps sending the empty Key. Across the
  43 REST services no passing variant is lost and no total changes;
  bedrock +15, route53 +13, lambda +8, cloudfront +2.
- Route53: route on the raw path, keeping interior empty segments, so an
  empty id reaches its op (NoSuchHostedZone etc.) instead of an
  undeclared 404 InvalidArgument; GET /hostedzone/ still lists.
- Lambda: validate LayerName (140 chars, model pattern) on all seven
  layer ops and CallbackId on the durable-execution callbacks, returning
  ValidationException with the AWS wording.
- Conformance: seed my-function's reserved concurrency only around
  GetFunctionConcurrency (its documented example needs 250), restored by
  a drop guard.
…account

LayerName validation follows the model's AWS region pattern and 12-digit
account, so a layer ARN fakecloud itself mints under --region local (or
a non-AWS --account-id) was rejected by every layer op. Exempt ARNs that
name the request's own region and account; anything else still has to
satisfy the pattern.
…53-lambda

# Conflicts:
#	crates/fakecloud-conformance/src/probe/response.rs
…/fakecloud into fix/conformance-route53-lambda
@vieiralucas
vieiralucas merged commit d29fcc0 into main Oct 17, 2026
158 checks passed
@vieiralucas
vieiralucas deleted the fix/conformance-route53-lambda branch October 17, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant