Skip to content

aws-smithy-types 1.7.0 breaks released aws-smithy-json 0.62.4 and 0.63.0 #4853

Description

@commonsensesoftware

Summary

Updating dependencies without changing application code causes compilation failures inside released AWS dependencies. aws-smithy-types 1.7.0 changes the public Document API incompatibly with 1.6.3. Both aws-smithy-json 0.62.4 and 0.63.0 allow the update through their declared dependency ranges but cannot compile against it.

The regression reproduces in an empty Rust library with only two dependencies. Neither AWS credentials, network requests, application code, nor unstable feature flags are needed.

Release timing and environment

The local crates.io index records these publication timestamps:

  • aws-smithy-types 1.6.3: 2026-09-03 18:37:02 UTC.
  • aws-smithy-types 1.7.0: 2026-09-14 22:22:23 UTC (15:22:23 PDT).

Reproduced on Linux x86_64 with rustc 1.97.1 (8bab26f4f 2026-07-14) and Cargo 1.97.1.

Minimal reproduction

Create a project with an empty src/lib.rs and this Cargo.toml:

[package]
name = "smithy-compat-repro"
version = "0.1.0"
edition = "2021"

[dependencies]
aws-smithy-json = "=0.62.4"
aws-smithy-types = "=1.7.0"

Run cargo check. It fails inside aws-smithy-json.

Repeat with aws-smithy-json = "=0.63.0": compilation also fails.

For each JSON version, change only the types constraint to aws-smithy-types = "=1.6.3" and rerun cargo check: compilation succeeds.

All four cases were executed locally with --offline using downloaded registry packages:

aws-smithy-json aws-smithy-types Result
0.62.4 1.7.0 Fails: E0308 and E0004
0.62.4 1.6.3 Passes
0.63.0 1.7.0 Fails: two E0308 errors and E0004
0.63.0 1.6.3 Passes

The sibling directories 0.62.4/ and 0.63.0/ contain the reproductions. The sibling json-*-types-*.log files contain complete compiler output for all four cases.

Incompatible public API changes

Comparison of the published src/document/mod.rs files shows:

  1. Document::Object(HashMap<String, Document>) became Document::Object(DocumentObject). Existing constructors passing a HashMap no longer type-check. An available From conversion does not preserve source compatibility because Rust does not implicitly apply it to enum constructor arguments.
  2. The previously exhaustive Document enum gained #[non_exhaustive]. Existing exhaustive matches now require a wildcard arm.
  3. The enum gained Blob, Timestamp, BigInteger, and BigDecimal variants. Adding variants to the previously exhaustive enum is independently a breaking API change.
  4. Document::as_object() changed from Option<&HashMap<String, Document>> to Option<&DocumentObject>; as_object_mut() similarly changed its mutable reference return type. These are additional public signature changes identified by source inspection, not separate diagnostics from the minimal JSON reproductions.

These changes to Document are unconditional. They are not gated behind the aws_sdk_unstable configuration used by the optional serde features.

Exact failing locations

aws-smithy-json 0.62.4

src/deserialize/token.rs:323:

error[E0308]: mismatched types
323 |             Ok(Document::Object(object))
    |                ---------------- ^^^^^^ expected `DocumentObject`, found `HashMap<String, Document>`

src/serialize.rs:36:

error[E0004]: non-exhaustive patterns: `&_` not covered
36 |         match value {
   |               ^^^^^ pattern `&_` not covered

The diagnostic identifies Document as non-exhaustive and requires a wildcard arm.

aws-smithy-json 0.63.0

The same failures occur at src/deserialize/token.rs:323 and src/serialize.rs:36. There is also an E0308 at src/codec/deserializer.rs:707:

707 |                 Ok(Document::Object(map))
    |                    ---------------- ^^^ expected `DocumentObject`, found `HashMap<String, Document>`

Why Cargo selects the incompatible combination

The published manifests declare:

  • aws-smithy-json 0.62.4 depends on aws-smithy-types = "1.4.4" (caret range >=1.4.4, <2.0.0).
  • aws-smithy-json 0.63.0 depends on aws-smithy-types = "1.6.1" (caret range >=1.6.1, <2.0.0).

Both ranges admit 1.7.0. Cargo correctly resolves and unifies these according to the declared compatibility ranges; rustc subsequently rejects the code. This is not a Cargo resolver failure or a requirement for multiple incompatible major versions of Smithy types.

In the affected application, the dependency paths are:

aws-config 1.8.14
  +-- aws-smithy-json 0.62.4
  +-- aws-sdk-sso 1.95.0 ------> aws-smithy-json 0.62.4
  +-- aws-sdk-ssooidc 1.97.0 --> aws-smithy-json 0.62.4
  +-- aws-sdk-sts 1.99.0 ------> aws-smithy-json 0.62.4

aws-sdk-s3 1.146.1 -----------> aws-smithy-json 0.63.0

Both JSON versions resolve against aws-smithy-types 1.7.0.

Updating aws-config alone to 1.10.1 was also tested: it still fails because aws-smithy-json 0.63.0 remains incompatible with types 1.7.0.

SemVer implications and requested upstream resolution

These are breaking changes within a stable 1.x release line. Cargo's SemVer guidance explicitly identifies adding non_exhaustive to an existing enum and adding variants to an exhaustive enum as major changes:

https://doc.rust-lang.org/cargo/reference/semver.html

Please restore source compatibility in the 1.x API, or publish the incompatible API under a major version and migrate dependents accordingly. Consider yanking the incompatible release and coordinating the disposition of newly published runtime releases that require it. Updating only new JSON releases would leave older already-published JSON versions with dependency ranges that still admit the incompatible types release.

Please include the four-case reproduction matrix in compatibility testing. Adding .into() and a wildcard arm to JSON code may fix compilation in a new JSON release, but does not restore compatibility for other existing users of the old public API; serialization of the new document variants also needs an explicit policy.

Verified downstream workaround

Add a direct dependency constraint aws-smithy-types = "=1.6.3" to the consuming crate. Cargo then automatically chooses these compatible versions:

Crate Failing selection Working selection
aws-smithy-types 1.7.0 1.6.3
aws-smithy-runtime-api 1.16.1 1.16.0
aws-smithy-runtime 1.14.1 1.14.0
aws-smithy-http-client 1.4.1 1.4.0
aws-smithy-eventstream 0.61.3 0.61.2
aws-sigv4 1.5.2 1.5.1
aws-runtime 1.9.3 1.9.2

The existing aws-config 1.8.14 and aws-sdk-s3 1.146.1 versions remain unchanged. The constraint works for both fresh dependency resolution and re-resolution of the failing lockfile. The actual affected crate passes cargo check -p legion-s3 --all-targets --all-features --offline with the manifest constraint.

Pinning only AWS config or S3 does not freeze their transitive dependencies. A library's own Cargo.lock also does not constrain dependency resolution in consuming applications, so the manifest constraint is necessary to carry the workaround downstream.

Application verification after applying the pin

  • cargo check -p legion-s3 --all-targets --all-features --offline: passed.
  • cargo test -p legion-s3 --locked --offline: all four unit tests passed; doc-tests passed (zero tests).
  • git diff --check: passed.
  • Full workspace checks and cargo-udeps execution were not run. The intentional pin is exempted using the repository's existing cargo-udeps metadata convention.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions