Repository: smithy-lang/smithy-rs (language: rust)

Issue:
Re-export `BuildError`



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml
index b4f5b3b8b6..a22d670ba9 100644
--- a/CHANGELOG.next.toml
+++ b/CHANGELOG.next.toml
@@ -16,3 +16,58 @@ message = "Fix aws-sdk-rust#930 (PutSnapshotBlock)"
 references = ["smithy-rs#3126", "aws-sdk-rust#930"]
 meta = { "breaking" = false, "tada" = false, "bug" = true }
 author = "rcoh"
+
+[[aws-sdk-rust]]
+message = "Fix exclusively setting the credentials provider at operation config-override time. It's now possible to set the credentials when an operation is sent (via `.config_override()`), rather than at client-creation time."
+references = ["smithy-rs#3156", "aws-sdk-rust#901"]
+meta = { "breaking" = false, "tada" = false, "bug" = true }
+author = "ysaito1001"
+
+[[smithy-rs]]
+message = """Enable conversion from `BuildError` into `SdkError` & `<service>::Error`. This allows customers to write the following code:
+```rust
+async fn do_a_thing(client: &Client) -> Result<SdkError<SomeOperationError>> {
+    client.run_operation().complex_field(ComplexField::builder()
+        .a("a")
+        .b("b")
+        .build()?
+    ).send().await?;
+}
+```
+
+Previously, `?` could not be used in this position.
+"""
+references = ["smithy-rs#3173", "smithy-rs#3171"]
+meta = { "breaking" = false, "tada" = true, "bug" = false }
+author = "rcoh"
+
+[[aws-sdk-rust]]
+message = """Enable conversion from `BuildError` into `SdkError` & `<service>::Error`. This allows customers to write the following code:
+```rust
+async fn create_table(dynamo_client: &Client) -> Result<(), SdkError<CreateTableError>> {
+    dynamo_client
+        .create_table()
+        .table_name("test")
+        .key_schema(
+            KeySchemaElement::builder()
+                .attribute_name("year")
+                .key_type(KeyType::Hash)
+                .build()?, // Previously, `?` could not be used here
+        )
+        .send()
+        .await?;
+    Ok(())
+}
+```
+
+Previously, `?` could not be used in this position.
+"""
+references = ["smithy-rs#3173", "smithy-rs#3171"]
+meta = { "breaking" = false, "tada" = true, "bug" = false }
+author = "rcoh"
+
+[[aws-sdk-rust]]
+message = "ProvideCredentials and SharedCredentialsProvider are now re-exported."
+references = ["smithy-rs#3173", "smithy-rs#3155"]
+meta = { "breaking" = false, "tada" = false, "bug" = false }
+author = "rcoh"
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCrateDocsDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCrateDocsDecorator.kt
index f167015ac2..047443d803 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCrateDocsDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCrateDocsDecorator.kt
@@ -119,11 +119,12 @@ internal class AwsCrateDocGenerator(private val codegenContext: ClientCodegenCon
         if (includeHeader) {
             template(asComments, escape("# $moduleName\n"))
         }
+        // NOTE: when you change this, you must also change SDK_README.md.hb
         template(
             asComments,
             """
-            **Please Note: The SDK is currently in Developer Preview and is intended strictly for
-            feedback purposes only. Do not use this SDK for production workloads.**${"\n"}
+            **Please Note: The SDK is currently released as a developer preview, without support or assistance for use
+            on production workloads. Any use in production is at your own risk.**${"\n"}
             """.trimIndent(),
         )
 
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt
index 93fb926ffe..caf995854f 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt
@@ -30,11 +30,9 @@ import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsSection
 import software.amazon.smithy.rust.codegen.core.util.serviceNameOrDefault
 
 private class Types(runtimeConfig: RuntimeConfig) {
-    private val smithyHttp = RuntimeType.smithyHttp(runtimeConfig)
     private val smithyTypes = RuntimeType.smithyTypes(runtimeConfig)
 
     val awsTypes = AwsRuntimeType.awsTypes(runtimeConfig)
-    val connectorError = smithyHttp.resolve("result::ConnectorError")
     val retryConfig = smithyTypes.resolve("retry::RetryConfig")
     val timeoutConfig = smithyTypes.resolve("timeout::TimeoutConfig")
 }
@@ -102,7 +100,6 @@ class AwsFluentClientDecorator : ClientCodegenDecorator {
 private class AwsFluentClientExtensions(private val codegenContext: ClientCodegenContext, private val types: Types) {
     private val codegenScope = arrayOf(
         "Arc" to RuntimeType.Arc,
-        "ConnectorError" to types.connectorError,
         "RetryConfig" to types.retryConfig,
         "TimeoutConfig" to types.timeoutConfig,
         "aws_types" to types.awsTypes,
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt
index 46d8e42734..9405f8a2fe 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt
@@ -7,20 +7,17 @@ package software.amazon.smithy.rustsdk
 
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
 import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
 import software.amazon.smithy.rust.codegen.client.smithy.customize.TestUtilFeature
 import software.amazon.smithy.rust.codegen.client.smithy.endpoint.supportedAuthSchemes
-import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
-import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
-import software.amazon.smithy.rust.codegen.core.rustlang.Writable
 import software.amazon.smithy.rust.codegen.core.rustlang.featureGateBlock
 import software.amazon.smithy.rust.codegen.core.rustlang.rust
 import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
 import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
 import software.amazon.smithy.rust.codegen.core.rustlang.writable
-import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
 import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
 import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
@@ -30,12 +27,6 @@ class CredentialsProviderDecorator : ClientCodegenDecorator {
     override val name: String = "CredentialsProvider"
     override val order: Byte = 0
 
-    override fun serviceRuntimePluginCustomizations(
-        codegenContext: ClientCodegenContext,
-        baseCustomizations: List<ServiceRuntimePluginCustomization>,
-    ): List<ServiceRuntimePluginCustomization> =
-        baseCustomizations + listOf(CredentialsIdentityResolverRegistration(codegenContext))
-
     override fun configCustomizations(
         codegenContext: ClientCodegenContext,
         baseCustomizations: List<ConfigCustomization>,
@@ -65,15 +56,23 @@ class CredentialsProviderDecorator : ClientCodegenDecorator {
 /**
  * Add a `.credentials_provider` field and builder to the `Config` for a given service
  */
-class CredentialProviderConfig(codegenContext: ClientCodegenContext) : ConfigCustomization() {
+class CredentialProviderConfig(private val codegenContext: ClientCodegenContext) : ConfigCustomization() {
     private val runtimeConfig = codegenContext.runtimeConfig
     private val codegenScope = arrayOf(
         *preludeScope,
-        "Credentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("Credentials"),
-        "ProvideCredentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
-            .resolve("provider::ProvideCredentials"),
-        "SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
-            .resolve("provider::SharedCredentialsProvider"),
+        "Credentials" to configReexport(AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("Credentials")),
+        "ProvideCredentials" to configReexport(
+            AwsRuntimeType.awsCredentialTypes(runtimeConfig)
+                .resolve("provider::ProvideCredentials"),
+        ),
+        "SharedCredentialsProvider" to configReexport(
+            AwsRuntimeType.awsCredentialTypes(runtimeConfig)
+                .resolve("provider::SharedCredentialsProvider"),
+        ),
+        "SIGV4A_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
+            .resolve("auth::sigv4a::SCHEME_ID"),
+        "SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
+            .resolve("auth::sigv4::SCHEME_ID"),
         "TestCredentials" to AwsRuntimeType.awsCredentialTypesTestUtil(runtimeConfig).resolve("Credentials"),
     )
 
@@ -103,16 +102,34 @@ class CredentialProviderConfig(codegenContext: ClientCodegenContext) : ConfigCus
                     *codegenScope,
                 )
 
-                rustTemplate(
+                rustBlockTemplate(
                     """
                     /// Sets the credentials provider for this service
-                    pub fn set_credentials_provider(&mut self, credentials_provider: #{Option}<#{SharedCredentialsProvider}>) -> &mut Self {
-                        self.config.store_or_unset(credentials_provider);
-                        self
-                    }
+                    pub fn set_credentials_provider(&mut self, credentials_provider: #{Option}<#{SharedCredentialsProvider}>) -> &mut Self
                     """,
                     *codegenScope,
-                )
+                ) {
+                    rustBlockTemplate(
+                        """
+                        if let Some(credentials_provider) = credentials_provider
+                        """,
+                        *codegenScope,
+                    ) {
+                        if (codegenContext.serviceShape.supportedAuthSchemes().contains("sigv4a")) {
+                            featureGateBlock("sigv4a") {
+                                rustTemplate(
+                                    "self.runtime_components.push_identity_resolver(#{SIGV4A_SCHEME_ID}, credentials_provider.clone());",
+                                    *codegenScope,
+                                )
+                            }
+                        }
+                        rustTemplate(
+                            "self.runtime_components.push_identity_resolver(#{SIGV4_SCHEME_ID}, credentials_provider);",
+                            *codegenScope,
+                        )
+                    }
+                    rust("self")
+                }
             }
 
             is ServiceConfig.DefaultForTests -> rustTemplate(
@@ -124,39 +141,3 @@ class CredentialProviderConfig(codegenContext: ClientCodegenContext) : ConfigCus
         }
     }
 }
-
-class CredentialsIdentityResolverRegistration(
-    private val codegenContext: ClientCodegenContext,
-) : ServiceRuntimePluginCustomization() {
-    private val runtimeConfig = codegenContext.runtimeConfig
-
-    override fun section(section: ServiceRuntimePluginSection): Writable = writable {
-        when (section) {
-            is ServiceRuntimePluginSection.RegisterRuntimeComponents -> {
-                rustBlockTemplate("if let Some(creds_provider) = ${section.serviceConfigName}.credentials_provider()") {
-                    val codegenScope = arrayOf(
-                        "SharedIdentityResolver" to RuntimeType.smithyRuntimeApi(runtimeConfig)
-                            .resolve("client::identity::SharedIdentityResolver"),
-                        "SIGV4A_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
-                            .resolve("auth::sigv4a::SCHEME_ID"),
-                        "SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
-                            .resolve("auth::sigv4::SCHEME_ID"),
-                    )
-
-                    if (codegenContext.serviceShape.supportedAuthSchemes().contains("sigv4a")) {
-                        featureGateBlock("sigv4a") {
-                            section.registerIdentityResolver(this) {
-                                rustTemplate("#{SIGV4A_SCHEME_ID}, creds_provider.clone()", *codegenScope)
-                            }
-                        }
-                    }
-                    section.registerIdentityResolver(this) {
-                        rustTemplate("#{SIGV4_SCHEME_ID}, creds_provider,", *codegenScope)
-                    }
-                }
-            }
-
-            else -> {}
-        }
-    }
-}
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RegionDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RegionDecorator.kt
index e7bf13e747..4e77e1c49b 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RegionDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RegionDecorator.kt
@@ -11,7 +11,7 @@ import software.amazon.smithy.model.node.Node
 import software.amazon.smithy.rulesengine.aws.language.functions.AwsBuiltIns
 import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
-import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
 import software.amazon.smithy.rust.codegen.client.smithy.endpoint.EndpointCustomization
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
@@ -22,7 +22,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
 import software.amazon.smithy.rust.codegen.core.rustlang.writable
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
-import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
 import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
 import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization
 import software.amazon.smithy.rust.codegen.core.util.dq
@@ -109,14 +108,6 @@ class RegionDecorator : ClientCodegenDecorator {
         }
     }
 
-    override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
-        if (usesRegion(codegenContext)) {
-            rustCrate.withModule(ClientRustModule.config) {
-                rust("pub use #T::Region;", region(codegenContext.runtimeConfig))
-            }
-        }
-    }
-
     override fun endpointCustomizations(codegenContext: ClientCodegenContext): List<EndpointCustomization> {
         if (!usesRegion(codegenContext)) {
             return listOf()
@@ -157,7 +148,7 @@ class RegionProviderConfig(codegenContext: ClientCodegenContext) : ConfigCustomi
     private val moduleUseName = codegenContext.moduleUseName()
     private val codegenScope = arrayOf(
         *preludeScope,
-        "Region" to region.resolve("Region"),
+        "Region" to configReexport(region.resolve("Region")),
     )
 
     override fun section(section: ServiceConfig) = writable {
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientReExports.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientReExports.kt
new file mode 100644
index 0000000000..6aaf638680
--- /dev/null
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientReExports.kt
@@ -0,0 +1,17 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package software.amazon.smithy.rust.codegen.client.smithy
+
+import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
+import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
+
+/** Returns a symbol for a type re-exported into crate::config
+ *  Although it is not always possible to use this, this is the preferred method for using types in config customizations
+ *  and ensures that your type will be re-exported if it is used.
+ */
+fun configReexport(type: RuntimeType): RuntimeType = RuntimeType.forInlineFun(type.name, module = ClientRustModule.config) {
+    rustTemplate("pub use #{type};", "type" to type)
+}
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt
index bb2f0c17f0..b573dbaab2 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt
@@ -13,7 +13,7 @@ import software.amazon.smithy.model.traits.HttpBasicAuthTrait
 import software.amazon.smithy.model.traits.HttpBearerAuthTrait
 import software.amazon.smithy.model.traits.HttpDigestAuthTrait
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
-import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.customize.AuthSchemeOption
 import software.amazon.smithy.rust.codegen.client.smithy.customize.AuthSchemeOption.StaticAuthSchemeOption
 import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
@@ -26,7 +26,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
 import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
 import software.amazon.smithy.rust.codegen.core.rustlang.writable
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
-import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
 import software.amazon.smithy.rust.codegen.core.util.dq
 import software.amazon.smithy.rust.codegen.core.util.getTrait
 import software.amazon.smithy.rust.codegen.core.util.letIf
@@ -38,6 +37,10 @@ private fun codegenScope(runtimeConfig: RuntimeConfig): Array<Pair<String, Any>>
     val authHttp = smithyRuntime.resolve("client::auth::http")
     val authHttpApi = smithyRuntimeApi.resolve("client::auth::http")
     return arrayOf(
+        "Token" to configReexport(smithyRuntimeApi.resolve("client::identity::http::Token")),
+        "Login" to configReexport(smithyRuntimeApi.resolve("client::identity::http::Login")),
+        "ResolveIdentity" to configReexport(smithyRuntimeApi.resolve("client::identity::ResolveIdentity")),
+
         "AuthSchemeId" to smithyRuntimeApi.resolve("client::auth::AuthSchemeId"),
         "ApiKeyAuthScheme" to authHttp.resolve("ApiKeyAuthScheme"),
         "ApiKeyLocation" to authHttp.resolve("ApiKeyLocation"),
@@ -48,11 +51,8 @@ private fun codegenScope(runtimeConfig: RuntimeConfig): Array<Pair<String, Any>>
         "HTTP_BASIC_AUTH_SCHEME_ID" to authHttpApi.resolve("HTTP_BASIC_AUTH_SCHEME_ID"),
         "HTTP_BEARER_AUTH_SCHEME_ID" to authHttpApi.resolve("HTTP_BEARER_AUTH_SCHEME_ID"),
         "HTTP_DIGEST_AUTH_SCHEME_ID" to authHttpApi.resolve("HTTP_DIGEST_AUTH_SCHEME_ID"),
-        "ResolveIdentity" to smithyRuntimeApi.resolve("client::identity::ResolveIdentity"),
-        "Login" to smithyRuntimeApi.resolve("client::identity::http::Login"),
         "SharedAuthScheme" to smithyRuntimeApi.resolve("client::auth::SharedAuthScheme"),
         "SharedIdentityResolver" to smithyRuntimeApi.resolve("client::identity::SharedIdentityResolver"),
-        "Token" to smithyRuntimeApi.resolve("client::identity::http::Token"),
     )
 }
 
@@ -135,25 +135,10 @@ class HttpAuthDecorator : ClientCodegenDecorator {
                 it + HttpAuthServiceRuntimePluginCustomization(codegenContext, authSchemes)
             }
         }
-
-    override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
-        val authSchemes = HttpAuthSchemes.from(codegenContext)
-        if (authSchemes.anyEnabled()) {
-            rustCrate.withModule(ClientRustModule.config) {
-                val codegenScope = codegenScope(codegenContext.runtimeConfig)
-                if (authSchemes.isTokenBased()) {
-                    rustTemplate("pub use #{Token};", *codegenScope)
-                }
-                if (authSchemes.isLoginBased()) {
-                    rustTemplate("pub use #{Login};", *codegenScope)
-                }
-            }
-        }
-    }
 }
 
 private class HttpAuthServiceRuntimePluginCustomization(
-    private val codegenContext: ClientCodegenContext,
+    codegenContext: ClientCodegenContext,
     private val authSchemes: HttpAuthSchemes,
 ) : ServiceRuntimePluginCustomization() {
     private val serviceShape = codegenContext.serviceShape
@@ -167,6 +152,7 @@ private class HttpAuthServiceRuntimePluginCustomization(
                         rustTemplate("#{SharedAuthScheme}::new(#{Scheme})", *codegenScope, "Scheme" to scheme)
                     }
                 }
+
                 fun registerNamedAuthScheme(name: String) {
                     registerAuthScheme {
                         rustTemplate("#{$name}::new()", *codegenScope)
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt
index 0feb667fe0..b53c2b2c2f 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt
@@ -6,6 +6,7 @@
 package software.amazon.smithy.rust.codegen.client.smithy.customizations
 
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
@@ -32,13 +33,13 @@ private class HttpConnectorConfigCustomization(
     private val moduleUseName = codegenContext.moduleUseName()
     private val codegenScope = arrayOf(
         *preludeScope,
-        "Connection" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::orchestrator::Connection"),
-        "HttpClient" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::HttpClient"),
-        "IntoShared" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("shared::IntoShared"),
-        "Resolver" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::config_override::Resolver"),
-        "SharedAsyncSleep" to RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep::SharedAsyncSleep"),
-        "SharedHttpClient" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::SharedHttpClient"),
-        "TimeoutConfig" to RuntimeType.smithyTypes(runtimeConfig).resolve("timeout::TimeoutConfig"),
+        "HttpClient" to configReexport(
+            RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::HttpClient"),
+        ),
+        "IntoShared" to configReexport(RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("shared::IntoShared")),
+        "SharedHttpClient" to configReexport(
+            RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::SharedHttpClient"),
+        ),
     )
 
     override fun section(section: ServiceConfig): Writable {
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/IdentityCacheDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/IdentityCacheDecorator.kt
index d3015e7693..f66fd6f288 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/IdentityCacheDecorator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/IdentityCacheDecorator.kt
@@ -6,6 +6,7 @@
 package software.amazon.smithy.rust.codegen.client.smithy.customizations
 
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
 import software.amazon.smithy.rust.codegen.core.rustlang.Writable
@@ -21,8 +22,8 @@ class IdentityCacheConfigCustomization(codegenContext: ClientCodegenContext) : C
         val api = RuntimeType.smithyRuntimeApi(rc)
         arrayOf(
             *preludeScope,
-            "ResolveCachedIdentity" to api.resolve("client::identity::ResolveCachedIdentity"),
-            "SharedIdentityCache" to api.resolve("client::identity::SharedIdentityCache"),
+            "ResolveCachedIdentity" to configReexport(api.resolve("client::identity::ResolveCachedIdentity")),
+            "SharedIdentityCache" to configReexport(api.resolve("client::identity::SharedIdentityCache")),
         )
     }
 
@@ -88,6 +89,7 @@ class IdentityCacheConfigCustomization(codegenContext: ClientCodegenContext) : C
                     *codegenScope,
                 )
             }
+
             is ServiceConfig.ConfigImpl -> {
                 rustTemplate(
                     """
@@ -99,7 +101,8 @@ class IdentityCacheConfigCustomization(codegenContext: ClientCodegenContext) : C
                     *codegenScope,
                 )
             }
-            else -> { }
+
+            else -> {}
         }
     }
 }
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/InterceptorConfigCustomization.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/InterceptorConfigCustomization.kt
index e6d48030f1..eecd7bb4a6 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/InterceptorConfigCustomization.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/InterceptorConfigCustomization.kt
@@ -6,6 +6,7 @@
 package software.amazon.smithy.rust.codegen.client.smithy.customizations
 
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
 import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
@@ -17,8 +18,8 @@ class InterceptorConfigCustomization(codegenContext: ClientCodegenContext) : Con
     private val runtimeConfig = codegenContext.runtimeConfig
 
     private val codegenScope = arrayOf(
-        "Intercept" to RuntimeType.intercept(runtimeConfig),
-        "SharedInterceptor" to RuntimeType.sharedInterceptor(runtimeConfig),
+        "Intercept" to configReexport(RuntimeType.intercept(runtimeConfig)),
+        "SharedInterceptor" to configReexport(RuntimeType.sharedInterceptor(runtimeConfig)),
     )
 
     override fun section(section: ServiceConfig) =
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt
index e44fce767f..ec09d34659 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt
@@ -7,6 +7,7 @@ package software.amazon.smithy.rust.codegen.client.smithy.customizations
 
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
 import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
 import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
 import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
@@ -25,7 +26,9 @@ class ResiliencyConfigCustomization(codegenContext: ClientCodegenContext) : Conf
     private val moduleUseName = codegenContext.moduleUseName()
     private val codegenScope = arrayOf(
         *preludeScope,
-        "AsyncSleep" to sleepModule.resolve("AsyncSleep"),
+        "AsyncSleep" to configReexport(sleepModule.resolve("AsyncSleep")),
+        "SharedAsyncSleep" to configReexport(sleepModule.resolve("SharedAsyncSleep")),
+        "Sleep" to configReexport(sleepModule.resolve("Sleep")),
         "ClientRateLimiter" to retries.resolve("ClientRateLimiter"),
         "ClientRateLimiterPartition" to retries.resolve("ClientRateLimiterPartition"),
         "debug" to RuntimeType.Tracing.resolve("debug"),
@@ -33,10 +36,9 @@ class ResiliencyConfigCustomization(codegenContext: ClientCodegenContext) : Conf
         "RetryConfig" to retryConfig.resolve("RetryConfig"),
         "RetryMode" to RuntimeType.smithyTypes(runtimeConfig).resolve("retry::RetryMode"),
         "RetryPartition" to retries.resolve("RetryPartition"),
-        "SharedAsyncSleep" to sleepModule.resolve("SharedAsyncSleep"),
-        "SharedRetryStrategy" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::retries::SharedRetryStrategy"),
+        "SharedRetryStrategy" to RuntimeType.smithyRuntimeApi(runtimeConfig)
+            .resolve("client::retries::SharedRetryStrategy"),
         "SharedTimeSource" to RuntimeType.smithyAsync(runtimeConfig).resolve("time::SharedTimeSource"),
-        "Sleep" to sleepModule.resolve("Sleep"),
         "StandardRetryStrategy" to retries.resolve("strategy::StandardRetryStrategy"),
         "SystemTime" to RuntimeType.std.resolve("time::SystemTime"),
         "TimeoutConfig" to timeoutModule.resolve("TimeoutConfig"),
@@ -286,7 +288,7 @@ class ResiliencyReExportCustomization(codegenContext: ClientCodegenContext) {
     fun extras(rustCrate: RustCrate) {
         rustCrate.withModule(ClientRustModule.config) {
             rustTemplate(
-                "pub use #{sleep}::{AsyncSleep, SharedAsyncSleep, Sleep};",
+                "pub use #{sleep}::{Sleep};",
                 "sleep" to RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep"),
             )
         }
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt
index aa3e39ad4e..9ef7c06e71 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt
@@ -30,6 +30,7 @@ import software.amazon.smithy.rust.codegen.core.smithy.customizations.AllowLints
 import software.amazon.smithy.rust.codegen.core.smithy.customizations.CrateVersionCustomization
 import software.amazon.smithy.rust.codegen.core.smithy.customizations.pubUseSmithyPrimitives
 import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsCustomization
+import software.amazon.smithy.rust.codegen.core.smithy.generators.operationBuildError
 
 val TestUtilFeature = Feature("test-util", false, listOf())
 
@@ -93,6 +94,8 @@ class RequiredCustomizations : ClientCodegenDecorator {
                 """
                 /// Error type returned by the client.
                 pub type SdkError<E, R = #{R}> = #{SdkError}<E, R>;
+                pub use #{BuildError};
+                pub use #{ConnectorError};
 
                 pub use #{DisplayErrorContext};
                 pub use #{ProvideErrorMetadata};
@@ -101,6 +104,9 @@ class RequiredCustomizations : ClientCodegenDecorator {
                 "ProvideErrorMetadata" to RuntimeType.smithyTypes(rc).resolve("error::metadata::ProvideErrorMetadata"),
                 "R" to RuntimeType.smithyRuntimeApi(rc).resolve("client::orchestrator::HttpResponse"),
                 "SdkError" to RuntimeType.sdkError(rc),
+                // this can't use the auto-rexport because the builder generator is defined in codegen core
+                "BuildError" to rc.operationBuildError(),
+                "ConnectorError" to RuntimeType.smithyRuntimeApi(rc).resolve("client::result::ConnectorError"),
             )
         }
 
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointConfigCustomization.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointConfigCustomization.kt
index e565aeefa9..f40f46284d 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointConfigCustomization.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointConfigCustomization.kt
@@ -32,7 +32,6 @@ internal class EndpointConfigCustomization(
     private val codegenScope = arrayOf(
         *preludeScope,
         "Params" to typesGenerator.paramsStruct(),
-        "IntoShared" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("shared::IntoShared"),
         "Resolver" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::config_override::Resolver"),
         "SharedEndpointResolver" to epModule.resolve("SharedEndpointResolver"),
         "StaticUriEndpointResolver" to epRuntimeModule.resolve("StaticUriEndpointResolver"),
@@ -90,7 +89,6 @@ internal class EndpointConfigCustomization(
                                 ##[allow(deprecated)]
                                 self.set_endpoint_resolver(
                                     endpoint_url.map(|url| {
-                                        use #{IntoShared};
                                         #{StaticUriEndpointResolver}::uri(url).into_shared()
                                     })
                                 );
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ClientRuntimeTypesReExportGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ClientRuntimeTypesReExportGenerator.kt
index 690bf41a0b..12bc55c8dc 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ClientRuntimeTypesReExportGenerator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ClientRuntimeTypesReExportGenerator.kt
@@ -24,9 +24,7 @@ class ClientRuntimeTypesReExportGenerator(
             rustTemplate(
                 """
                 pub use #{ConfigBag};
-                pub use #{Intercept};
                 pub use #{RuntimeComponents};
-                pub use #{SharedInterceptor};
                 pub use #{IdentityCache};
                 """,
                 "ConfigBag" to RuntimeType.configBag(rc),
@@ -35,19 +33,6 @@ class ClientRuntimeTypesReExportGenerator(
                 "SharedInterceptor" to RuntimeType.sharedInterceptor(rc),
                 "IdentityCache" to RuntimeType.smithyRuntime(rc).resolve("client::identity::IdentityCache"),
             )
-
-            if (codegenContext.enableUserConfigurableRuntimePlugins) {
-                rustTemplate(
-                    """
-                    pub use #{runtime_plugin}::{RuntimePlugin, SharedRuntimePlugin};
-                    pub use #{config_bag}::FrozenLayer;
-                    pub use #{RuntimeComponentsBuilder};
-                    """,
-                    "runtime_plugin" to RuntimeType.smithyRuntimeApi(rc).resolve("client::runtime_plugin"),
-                    "config_bag" to RuntimeType.smithyTypes(rc).resolve("config_bag"),
-                    "RuntimeComponentsBuilder" to RuntimeType.runtimeComponentsBuilder(rc),
-                )
-            }
         }
         rustCrate.withModule(ClientRustModule.Config.endpoint) {
             rustTemplate(
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceRuntimePluginGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceRuntimePluginGenerator.kt
index 60015d897c..875e8ef73e 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceRuntimePluginGenerator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceRuntimePluginGenerator.kt
@@ -51,10 +51,6 @@ sealed class ServiceRuntimePluginSection(name: String) : Section(name) {
             writer.rust("runtime_components.set_endpoint_resolver(Some(#T));", resolver)
         }
 
-        fun registerIdentityResolver(writer: RustWriter, identityResolver: Writable) {
-            writer.rust("runtime_components.push_identity_resolver(#T);", identityResolver)
-        }
-
         fun registerRetryClassifier(writer: RustWriter, classifier: Writable) {
             writer.rust("runtime_components.push_retry_classifier(#T);", classifier)
         }
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/config/ServiceConfigGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/config/ServiceConfigGenerator.kt
index bc3eea9762..347c731b20 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/config/ServiceConfigGenerator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/config/ServiceConfigGenerator.kt
@@ -13,6 +13,7 @@ import software.amazon.smithy.model.shapes.ServiceShape
 import software.amazon.smithy.model.traits.IdempotencyTokenTrait
 import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
 import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
+import software.amazon.smithy.rust.codegen.client.smithy.configReexport
 import software.amazon.smithy.rust.codegen.client.smithy.customize.TestUtilFeature
 import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
 import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
@@ -271,12 +272,12 @@ class ServiceConfigGenerator(
         "CloneableLayer" to smithyTypes.resolve("config_bag::CloneableLayer"),
         "ConfigBag" to RuntimeType.configBag(codegenContext.runtimeConfig),
         "Cow" to RuntimeType.Cow,
-        "FrozenLayer" to smithyTypes.resolve("config_bag::FrozenLayer"),
-        "Layer" to smithyTypes.resolve("config_bag::Layer"),
+        "FrozenLayer" to configReexport(smithyTypes.resolve("config_bag::FrozenLayer")),
+        "Layer" to configReexport(smithyTypes.resolve("config_bag::Layer")),
         "Resolver" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::config_override::Resolver"),
-        "RuntimeComponentsBuilder" to RuntimeType.runtimeComponentsBuilder(runtimeConfig),
-        "RuntimePlugin" to RuntimeType.runtimePlugin(runtimeConfig),
-        "SharedRuntimePlugin" to RuntimeType.sharedRuntimePlugin(runtimeConfig),
+        "RuntimeComponentsBuilder" to configReexport(RuntimeType.runtimeComponentsBuilder(runtimeConfig)),
+        "RuntimePlugin" to configReexport(RuntimeType.runtimePlugin(runtimeConfig)),
+        "SharedRuntimePlugin" to configReexport(RuntimeType.sharedRuntimePlugin(runtimeConfig)),
         "runtime_plugin" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::runtime_plugin"),
     )
 
diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ServiceErrorGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ServiceErrorGenerator.kt
index c11fbfecf8..1c70bf639d 100644
--- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ServiceErrorGenerator.kt
+++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ServiceErrorGenerator.kt
@@ -27,6 +27,7 @@ import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.unhandledError
 import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
 import software.amazon.smithy.rust.codegen.core.smithy.customize.writeCustomizations
+import software.amazon.smithy.rust.codegen.core.smithy.generators.operationBuildError
 import software.amazon.smithy.rust.codegen.core.smithy.transformers.allErrors
 import software.amazon.smithy.rust.codegen.core.smithy.transformers.eventStreamErrors
 
@@ -65,6 +66,7 @@ class ServiceErrorGenerator(
         crate.withModule(RustModule.private("error_meta")) {
             renderDefinition()
             renderImplDisplay()
+            renderImplFromBuildError()
             // Every operation error can be converted into service::Error
             operations.forEach { operationShape ->
                 // operation errors
@@ -108,6 +110,21 @@ class ServiceErrorGenerator(
         }
     }
 
+    private fun RustWriter.renderImplFromBuildError() {
+        rustTemplate(
+            """
+            impl From<#{BuildError}> for Error {
+                fn from(value: #{BuildError}) -> Self {
+                    Error::Unhandled(#{Unhandled}::builder().source(value).build())
+                }
+            }
+
+            """,
+            "BuildError" to codegenContext.runtimeConfig.operationBuildError(),
+            "Unhandled" to unhandledError(codegenContext.runtimeConfig),
+        )
+    }
+
     private fun RustWriter.renderImplFrom(errorSymbol: Symbol, errors: List<ShapeId>) {
         if (errors.isNotEmpty() || CodegenTarget.CLIENT == codegenContext.target) {
             val operationErrors = errors.map { model.expectShape(it) }
diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/ProtocolFunctions.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/ProtocolFunctions.kt
index 53bdfc009f..c468fdca0b 100644
--- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/ProtocolFunctions.kt
+++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/ProtocolFunctions.kt
@@ -18,6 +18,10 @@ import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
 import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
 import software.amazon.smithy.rust.codegen.core.smithy.contextName
+import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticInputTrait
+import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticOutputTrait
+import software.amazon.smithy.rust.codegen.core.util.hasTrait
+import software.amazon.smithy.rust.codegen.core.util.letIf
 import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
 
 /**
@@ -139,10 +143,13 @@ internal fun RustSymbolProvider.shapeModuleName(serviceShape: ServiceShape?, sha
 
 /** Creates a unique name for a ser/de function. */
 fun RustSymbolProvider.shapeFunctionName(serviceShape: ServiceShape?, shape: Shape): String {
+    val extras = "".letIf(shape.hasTrait<SyntheticOutputTrait>()) {
+        it + "_output"
+    }.letIf(shape.hasTrait<SyntheticInputTrait>()) { it + "_input" }
     val containerName = when (shape) {
         is MemberShape -> model.expectShape(shape.container).contextName(serviceShape).toSnakeCase()
         else -> shape.contextName(serviceShape).toSnakeCase()
-    }
+    } + extras
     return when (shape) {
         is MemberShape -> shape.memberName.toSnakeCase()
         is DocumentShape -> "document"
diff --git a/rust-runtime/aws-smithy-runtime-api/src/client/result.rs b/rust-runtime/aws-smithy-runtime-api/src/client/result.rs
index 4d9182a073..93013abdd8 100644
--- a/rust-runtime/aws-smithy-runtime-api/src/client/result.rs
+++ b/rust-runtime/aws-smithy-runtime-api/src/client/result.rs
@@ -7,6 +7,7 @@
 
 use crate::client::connection::ConnectionMetadata;
 use aws_smithy_types::error::metadata::{ProvideErrorMetadata, EMPTY_ERROR_METADATA};
+use aws_smithy_types::error::operation::BuildError;
 use aws_smithy_types::error::ErrorMetadata;
 use aws_smithy_types::retry::ErrorKind;
 use std::error::Error;
@@ -482,6 +483,12 @@ where
     }
 }
 
+impl<E, R> From<BuildError> for SdkError<E, R> {
+    fn from(value: BuildError) -> Self {
+        SdkError::ConstructionFailure(ConstructionFailure::builder().source(value).build())
+    }
+}
+
 impl<E, R> ProvideErrorMetadata for SdkError<E, R>
 where
     E: ProvideErrorMetadata,
diff --git a/tools/ci-scripts/check-only-aws-sdk-services b/tools/ci-scripts/check-only-aws-sdk-services
index d1e0ea754e..b15c4133b3 100755
--- a/tools/ci-scripts/check-only-aws-sdk-services
+++ b/tools/ci-scripts/check-only-aws-sdk-services
@@ -13,7 +13,6 @@ cd aws-sdk
 sed -i '/"examples\//d' Cargo.toml
 
 cargo check --all-targets --all-features
-RUSTDOCFLAGS="--cfg docsrs" cargo +"${RUST_NIGHTLY_VERSION}" doc --no-deps --document-private-items --all-features
 
 for test_dir in tests/*; do
     if [ -f "${test_dir}/Cargo.toml" ]; then


Test patch:
diff --git a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/CredentialProviderConfigTest.kt b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/CredentialProviderConfigTest.kt
index 87f832cc7e..5b6a81f069 100644
--- a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/CredentialProviderConfigTest.kt
+++ b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/CredentialProviderConfigTest.kt
@@ -7,6 +7,10 @@ package software.amazon.smithy.rustsdk
 
 import org.junit.jupiter.api.Test
 import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
+import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
+import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
+import software.amazon.smithy.rust.codegen.core.testutil.integrationTest
+import software.amazon.smithy.rust.codegen.core.testutil.tokioTest
 
 internal class CredentialProviderConfigTest {
     @Test
@@ -14,4 +18,54 @@ internal class CredentialProviderConfigTest {
         val codegenContext = awsTestCodegenContext()
         validateConfigCustomizations(codegenContext, CredentialProviderConfig(codegenContext))
     }
+
+    @Test
+    fun `configuring credentials provider at operation level should work`() {
+        awsSdkIntegrationTest(SdkCodegenIntegrationTest.model) { ctx, rustCrate ->
+            val rc = ctx.runtimeConfig
+            val codegenScope = arrayOf(
+                *RuntimeType.preludeScope,
+                "capture_request" to RuntimeType.captureRequest(rc),
+                "Credentials" to AwsRuntimeType.awsCredentialTypesTestUtil(rc)
+                    .resolve("Credentials"),
+                "Region" to AwsRuntimeType.awsTypes(rc).resolve("region::Region"),
+            )
+            rustCrate.integrationTest("credentials_provider") {
+                // per https://github.com/awslabs/aws-sdk-rust/issues/901
+                tokioTest("configuring_credentials_provider_at_operation_level_should_work") {
+                    val moduleName = ctx.moduleUseName()
+                    rustTemplate(
+                        """
+                        let (http_client, _rx) = #{capture_request}(None);
+                        let client_config = $moduleName::Config::builder()
+                            .http_client(http_client)
+                            .build();
+
+                        let client = $moduleName::Client::from_conf(client_config);
+
+                        let credentials = #{Credentials}::new(
+                            "test",
+                            "test",
+                            #{None},
+                            #{None},
+                            "test",
+                        );
+                        let operation_config_override = $moduleName::Config::builder()
+                            .credentials_provider(credentials.clone())
+                            .region(#{Region}::new("us-west-2"));
+
+                        let _ = client
+                            .some_operation()
+                            .customize()
+                            .config_override(operation_config_override)
+                            .send()
+                            .await
+                            .expect("success");
+                        """,
+                        *codegenScope,
+                    )
+                }
+            }
+        }
+    }
 }
diff --git a/aws/sdk/integration-tests/dynamodb/tests/build-errors.rs b/aws/sdk/integration-tests/dynamodb/tests/build-errors.rs
new file mode 100644
index 0000000000..00fc07e716
--- /dev/null
+++ b/aws/sdk/integration-tests/dynamodb/tests/build-errors.rs
@@ -0,0 +1,41 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+use aws_sdk_dynamodb::error::SdkError;
+use aws_sdk_dynamodb::operation::create_table::CreateTableError;
+use aws_sdk_dynamodb::types::{KeySchemaElement, KeyType};
+use aws_sdk_dynamodb::Client;
+
+#[allow(dead_code)]
+async fn create_table_test(client: &Client) -> Result<(), SdkError<CreateTableError>> {
+    let _just_checking_compilation = client
+        .create_table()
+        .table_name("test")
+        .key_schema(
+            KeySchemaElement::builder()
+                .attribute_name("year")
+                .key_type(KeyType::Hash)
+                .build()?,
+        )
+        .send()
+        .await;
+    Ok(())
+}
+
+#[allow(dead_code)]
+async fn create_table_test_super_error(client: &Client) -> Result<(), aws_sdk_dynamodb::Error> {
+    let _just_checking_compilation = client
+        .create_table()
+        .table_name("test")
+        .key_schema(
+            KeySchemaElement::builder()
+                .attribute_name("year")
+                .key_type(KeyType::Hash)
+                .build()?,
+        )
+        .send()
+        .await;
+    Ok(())
+}
diff --git a/aws/sdk/integration-tests/kms/tests/integration.rs b/aws/sdk/integration-tests/kms/tests/integration.rs
index ed534f61bd..6cba0de93d 100644
--- a/aws/sdk/integration-tests/kms/tests/integration.rs
+++ b/aws/sdk/integration-tests/kms/tests/integration.rs
@@ -52,7 +52,7 @@ async fn generate_random() {
             .header("content-type", "application/x-amz-json-1.1")
             .header("x-amz-target", "TrentService.GenerateRandom")
             .header("content-length", "20")
-            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target;x-amz-user-agent, Signature=53dcf70f6f852cb576185dcabef5aaa3d068704cf1b7ea7dc644efeaa46674d7")
+            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=703f72fe50c310e3ee1a7a106df947b980cb91bc8bad7a4a603b057096603aed")
             .header("x-amz-date", "20090213T233130Z")
             .header("user-agent", "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0")
             .header("x-amz-user-agent", "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0")
diff --git a/aws/sdk/integration-tests/qldbsession/tests/integration.rs b/aws/sdk/integration-tests/qldbsession/tests/integration.rs
index 6cdb32d1f1..fbc8b0a00f 100644
--- a/aws/sdk/integration-tests/qldbsession/tests/integration.rs
+++ b/aws/sdk/integration-tests/qldbsession/tests/integration.rs
@@ -20,7 +20,7 @@ async fn signv4_use_correct_service_name() {
             .header("content-type", "application/x-amz-json-1.0")
             .header("x-amz-target", "QLDBSession.SendCommand")
             .header("content-length", "49")
-            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/qldb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target;x-amz-user-agent, Signature=9a07c60550504d015fb9a2b0f1b175a4d906651f9dd4ee44bebb32a802d03815")
+            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/qldb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=e8d50282fa369adf05f33a5b32e3ce2a7582edc902312c59de311001a97426d9")
             // qldbsession uses the signing name 'qldb' in signature _________________________^^^^
             .header("x-amz-date", "20090213T233130Z")
             .header("user-agent", "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0")
diff --git a/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs b/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs
index 3b6bd97002..f139a28b0f 100644
--- a/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs
+++ b/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs
@@ -88,7 +88,7 @@ async fn test_s3_signer_with_naughty_string_metadata() {
 
     // This is a snapshot test taken from a known working test result
     let snapshot_signature =
-        "Signature=a5115604df66219874a9e5a8eab4c9f7a28c992ab2d918037a285756c019f3b2";
+        "Signature=733dba2f1ca3c9a39f4eef3a6750a71eff00297cd765408ad3cef5dcdc44d642";
     assert!(
         auth_header .contains(snapshot_signature),
         "authorization header signature did not match expected signature: got {}, expected it to contain {}",
diff --git a/aws/sdk/integration-tests/s3/tests/normalize-uri-path.rs b/aws/sdk/integration-tests/s3/tests/normalize-uri-path.rs
index 11ee0f7b09..367aa19682 100644
--- a/aws/sdk/integration-tests/s3/tests/normalize-uri-path.rs
+++ b/aws/sdk/integration-tests/s3/tests/normalize-uri-path.rs
@@ -41,7 +41,7 @@ async fn test_operation_should_not_normalize_uri_path() {
     let expected_uri = "https://test-bucket-ad7c9f01-7f7b-4669-b550-75cc6d4df0f1.s3.us-east-1.amazonaws.com/a/.././b.txt?x-id=PutObject";
     assert_eq!(actual_uri, expected_uri);
 
-    let expected_sig = "Signature=2ac540538c84dc2616d92fb51d4fc6146ccd9ccc1ee85f518a1a686c5ef97b86";
+    let expected_sig = "Signature=404fb9502378c8f46fb83544848c42d29d55610a14b4bed9577542e49e549d08";
     assert!(
         actual_auth.contains(expected_sig),
         "authorization header signature did not match expected signature: expected {} but not found in {}",
diff --git a/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs b/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs
index 2e9f8bcaff..902d07933b 100644
--- a/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs
+++ b/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs
@@ -44,7 +44,7 @@ async fn test_s3_signer_query_string_with_all_valid_chars() {
 
     // This is a snapshot test taken from a known working test result
     let snapshot_signature =
-        "Signature=9a931d20606f93fa4e5553602866a9b5ccac2cd42b54ae5a4b17e4614fb443ce";
+        "Signature=740feb1de3968a643e68fb1a17c415d98dd6a1cc28782fb1ef6157586548c747";
     assert!(
         auth_header
             .contains(snapshot_signature),
diff --git a/aws/sdk/integration-tests/s3/tests/signing-it.rs b/aws/sdk/integration-tests/s3/tests/signing-it.rs
index 450f4ba43f..d0106aaded 100644
--- a/aws/sdk/integration-tests/s3/tests/signing-it.rs
+++ b/aws/sdk/integration-tests/s3/tests/signing-it.rs
@@ -15,7 +15,7 @@ use aws_smithy_types::body::SdkBody;
 async fn test_signer() {
     let http_client = StaticReplayClient::new(vec![ReplayEvent::new(
         http::Request::builder()
-            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-user-agent, Signature=27e3f59ec3cffaa10e4f1c92112e8fb62d468a04cd32be39e68215f830404dbb")
+            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=d8ea22461a59cc1cbeb01fa093423ffafcb7695197ba2409b477216a4be2c104")
             .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=prefix~")
             .body(SdkBody::empty())
             .unwrap(),
diff --git a/aws/sdk/integration-tests/s3control/tests/signing-it.rs b/aws/sdk/integration-tests/s3control/tests/signing-it.rs
index 7917b836eb..7b06289a1c 100644
--- a/aws/sdk/integration-tests/s3control/tests/signing-it.rs
+++ b/aws/sdk/integration-tests/s3control/tests/signing-it.rs
@@ -15,8 +15,8 @@ async fn test_signer() {
         http::Request::builder()
             .header("authorization",
                     "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/s3/aws4_request, \
-                    SignedHeaders=host;x-amz-account-id;x-amz-content-sha256;x-amz-date;x-amz-user-agent, \
-                    Signature=0102a74cb220f8445c4efada17660572ff813e07b524032ec831e8c2514be903")
+                    SignedHeaders=host;x-amz-account-id;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, \
+                    Signature=01a71226e959c7b0b998adf26fa266f9c3612df57a60b187d549822e86d90667")
             .uri("https://test-bucket.s3-control.us-east-1.amazonaws.com/v20180820/accesspoint")
             .body(SdkBody::empty())
             .unwrap(),
diff --git a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/NamingObstacleCourseTest.kt b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/NamingObstacleCourseTest.kt
index aba0edc1a5..addc4d8f1e 100644
--- a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/NamingObstacleCourseTest.kt
+++ b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/NamingObstacleCourseTest.kt
@@ -6,7 +6,10 @@
 package software.amazon.smithy.rust.codegen.client.smithy
 
 import org.junit.jupiter.api.Test
+import software.amazon.smithy.aws.traits.protocols.RestJson1Trait
+import software.amazon.smithy.aws.traits.protocols.RestXmlTrait
 import software.amazon.smithy.rust.codegen.client.testutil.clientIntegrationTest
+import software.amazon.smithy.rust.codegen.core.testutil.NamingObstacleCourseTestModels.reusedInputOutputShapesModel
 import software.amazon.smithy.rust.codegen.core.testutil.NamingObstacleCourseTestModels.rustPreludeEnumVariantsModel
 import software.amazon.smithy.rust.codegen.core.testutil.NamingObstacleCourseTestModels.rustPreludeEnumsModel
 import software.amazon.smithy.rust.codegen.core.testutil.NamingObstacleCourseTestModels.rustPreludeOperationsModel
@@ -32,4 +35,14 @@ class NamingObstacleCourseTest {
     fun `test Rust prelude enum variant names compile`() {
         clientIntegrationTest(rustPreludeEnumVariantsModel()) { _, _ -> }
     }
+
+    @Test
+    fun `test reuse of input and output shapes json`() {
+        clientIntegrationTest(reusedInputOutputShapesModel(RestJson1Trait.builder().build()))
+    }
+
+    @Test
+    fun `test reuse of input and output shapes xml`() {
+        clientIntegrationTest(reusedInputOutputShapesModel(RestXmlTrait.builder().build()))
+    }
 }
diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/NamingObstacleCourseTestModels.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/NamingObstacleCourseTestModels.kt
index c45a7d0992..72979545b9 100644
--- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/NamingObstacleCourseTestModels.kt
+++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/NamingObstacleCourseTestModels.kt
@@ -6,6 +6,7 @@
 package software.amazon.smithy.rust.codegen.core.testutil
 
 import software.amazon.smithy.model.Model
+import software.amazon.smithy.model.traits.Trait
 import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
 
 object NamingObstacleCourseTestModels {
@@ -169,4 +170,61 @@ object NamingObstacleCourseTestModels {
             """,
         )
     }.toString().asSmithyModel()
+
+    /**
+     * This targets two bug classes:
+     * - operation inputs used as nested outputs
+     * - operation outputs used as nested outputs
+     */
+    fun reusedInputOutputShapesModel(protocol: Trait) = """
+        namespace test
+        use ${protocol.toShapeId()}
+        use aws.api#service
+        @${protocol.toShapeId().name}
+        @service(sdkId: "test")
+        service Service {
+            version: "2006-03-01",
+            operations: [GetThing, ReuseGetThingIO]
+        }
+
+        // re-use get thing output in a list & in an operation
+        @http(uri: "/SomeOperation2", method: "POST")
+        operation GetThing {
+            output: GetThingOutput
+            input: GetThingInput
+        }
+
+        // an operation that re-uses the input and output shapes from `GetThing` above. this has caused issues in the
+        // past with operation/input shape confusion during function signature generation
+        @http(uri: "/SomeOperation3", method: "POST")
+        operation ReuseGetThingIO {
+            input: GetThingNested
+            output: GetThingNested
+        }
+
+        structure GetThingOutput {
+            @required
+            meta: String
+        }
+
+        structure GetThingInput {
+            @required
+            meta: String
+        }
+
+        // nested structure which reuses input and output shapes internally
+        structure GetThingNested {
+            thingsOut: GetThingOutputList,
+            thingsIn: GetThingInputList,
+            thingOut: GetThingOutput,
+            thingIn: GetThingInput
+        }
+
+        list GetThingOutputList {
+            member: GetThingOutput
+        }
+        list GetThingInputList {
+            member: GetThingInput
+        }
+    """.asSmithyModel()
 }
diff --git a/tools/ci-scripts/check-aws-sdk-smoketest-docs-clippy-udeps b/tools/ci-scripts/check-aws-sdk-smoketest-docs-clippy-udeps
index 38942ef067..b3b0ade515 100755
--- a/tools/ci-scripts/check-aws-sdk-smoketest-docs-clippy-udeps
+++ b/tools/ci-scripts/check-aws-sdk-smoketest-docs-clippy-udeps
@@ -10,7 +10,7 @@ set -eux
 pushd aws-sdk-smoketest &>/dev/null
 
 # Override "fail on warning" for smoke test docs since DynamoDB's modeled docs cause rustdoc warnings
-RUSTDOCFLAGS="" cargo doc --no-deps --document-private-items --all-features
+RUSTDOCFLAGS="--cfg docsrs" cargo +"${RUST_NIGHTLY_VERSION}" doc --no-deps --document-private-items --all-features
 
 cargo clippy --all-features
 cargo +"${RUST_NIGHTLY_VERSION}" udeps