-
Notifications
You must be signed in to change notification settings - Fork 224
Description
Description
We are running the AWS SDK for Rust in a browser environment (wasm32-unknown-unknown). We explicitly configure a custom, WASM-compatible TimeSource (wrapping js_sys::Date) on the SdkConfig to ensure the SDK never attempts to call SystemTime.
However, after a recent update to aws-smithy-runtime (commit 26c59c2), the SDK ignores this configured time source during the initialization of the default StandardRetryStrategy and panics immediately upon Client construction.
Our web application has been working until we upgraded to aws-smithy-runtime version 1.9.6. Because of this current change we now have to pin our aws-smithy-runtime version to 1.9.5.
The Regression
The commit 26c59c2 introduced a creation_time field to the TokenBucket struct to support time-based refills.
The Default implementation for TokenBucket initializes this field by creating SharedTimeSource. As defined in aws-smithy-async, this default implementation falls back to SystemTimeSource, which unconditionally calls SystemTime::now().
1. The Trigger (TokenBucket):
rust-runtime/aws-smithy-runtime/src/client/retries/token_bucket.rs
impl Default for TokenBucket {
fn default() -> Self {
let time_source = SharedTimeSource::default(); // <--- Creates unsafe default source
Self {
// ...
creation_time: time_source.now(), // <--- Panic triggers here
time_source,
}
}
}2. The Root Cause (SharedTimeSource): in rust-runtime/aws-smithy-async/src/time.rs, SharedTimeSource::default() utilizes TimeSource::default() which in turn defaults to SystemTimeSource and performs the WASM-incompatible call:
impl TimeSource for SystemTimeSource {
fn now(&self) -> SystemTime {
SystemTime::now() // <--- Panics on wasm32-unknown-unknown
}
}Why this is a Bug
-
Contract Violation: The SDK offers a
.time_source()configuration method onSdkConfig. If a user provides this, the SDK must use it for all time-related operations. Falling back toSystemTimeimplicitly viaDefault::default()violates this contract. Our web application has been working until we upgraded toaws-smithy-runtime1.9.6. Because of this current change we now have to pin to version 1.9.5. -
Target Incompatibility: On
wasm32-unknown-unknown,SystemTime::now()panics. By initializing eagerly withSystemTimeinstead of the configured source, the SDK becomes unusable in browser environments. -
No Workaround: TokenBucket is in a private module (
aws_smithy_runtime::client::retries::token_bucket), so we cannot manually construct it with the correct time source to override this broken default.
Reproduction Steps
-
Target
wasm32-unknown-unknown. -
Configure an SDK client (e.g., S3) with a custom
TimeSource(usingjs_sys). -
Use
BehaviorVersion::latest()(which enables the standard retry strategy). -
Result: Panic at runtime during client construction. The custom
TimeSourceis ignored;SystemTime::now()is called by theTokenBucketdefault initializer.
Proposed Fix
The TokenBucket (and StandardRetryStrategy) should not use Default::default() if it implies a hard dependency on SystemTime.
Instead, the TokenBucket should be constructed using the TimeSource available in the RuntimeComponents or ConfigBag during the client configuration phase, ensuring that if a user provides a custom source, it is respected throughout the entire client lifecycle.
Context
Commit: 26c59c21b638bbd33a9f46060ff8cc8d4c9df67c (approx Dec 19, 2025)
Component: aws-smithy-runtime / aws-smithy-async
Target: wasm32-unknown-unknown