You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[aws_lambda_events] No longer able to construct response types a lambda may return as a response (they are non_exhaustive) #1060
A number of the types in this crate are responses that a lambda might return. With the recent change to mark structs as non_exhaustive, these types can no longer be constructed. Some examples:
I'm sure there are other response types in this crate that lambdas would construct, but these are the ones I'm currently constructing and am no longer able to after they've been marked non_exhaustive.
Hi @dcormier , the intended API now when directly constructing would be to use ..Default::default() to guard against unknown fields. Does that work for you? I do think it would be good to have some examples demonstrating this...
These were changed because it was constantly forcing semver bumps every update and was forcing consumers to either update their code or be frozen in time.
Ah, my mistake. This is running afoul of: rust-lang/lang-team#143 , which doesn't seem to have much traction.
It sounds like at minimum we should update the official example to compile properly (@PartiallyUntyped ).
But, agreed that abandoning struct literals is not ideal. This is an awkward situation, since we definitely can't maintain the library with reasonable stability without #[non_exhaustive]
Perhaps some sort of non-default feature flag like features = ["experimental-non-exhaustive"] that has lesser semver guarantees?
Yep, encountered the same issue here. I agree with some of the previous comments, but I think the new way of building responses is not intuitive to use.
One of the options we are considering is providing automatically generated builders; the pattern will follow the same practices AWS SDK provides, in that you create a builder, set the fields you need, and then call build().
Do you think that might improve ergonomics?
It might be a step forward, but I suspect the code might still be quite verbose in practice. It would be nice so see some examples for what you have in mind.
Is there an argument against crafting finely tuned utility functions like the ones proposed in #1063?
for record in event.payload.records {
let message_id = record.message_id.clone().unwrap_or_default();
// Try to process the message
if let Err(e) = process_record(&record).await {
println!("Failed to process message {}: {}", message_id, e);
// Add to failures list so it will be retried
batch_item_failures.push(
SqsBatchItemFailure::builder()
.item_identifier(message_id)
.build()
);
}
}
Looks pretty good to me! 🎉
Probably a little bit more verbose than what I am suggesting with #1063, but I get that this is probably more idiomatic (and easier to generate rather than having to write all of it manually)
I know it's re:Invent season and everyone is probably super busy with it but I am curious to know if there was any progress with the discussion here or any consideration given to #1063.
Hey @lmammino , @PartiallyUntyped is currently OOO so the "codegenned automatic builders" will take some time.
Personally, it seems fine to me to also have custom, hand-written, even-more-ergonomic constructors for types where desired, such as #1063. Need to discuss with other maintainers but I'll at least give the PR a read-through in the meantime to reduce future churn.
(EDIT: Yeah, I got everybody's blessing to review #1063 as-is regardless of codegen plans)
Cannot create ApiGatewayV2CustomAuthorizerSimpleResponse<MyContext> if MyContext has no Default.
use aws_lambda_events::event::apigw::{ApiGatewayV2CustomAuthorizerSimpleResponse,ApiGatewayV2CustomAuthorizerV2Request,};use lambda_runtime::LambdaEvent;pub(crate)asyncfnfunction_handler(event:LambdaEvent<ApiGatewayV2CustomAuthorizerV2Request>,) -> Result<ApiGatewayV2CustomAuthorizerSimpleResponse<MyContext>, lambda_runtime::Error>{letmut output:ApiGatewayV2CustomAuthorizerSimpleResponse<MyContext> =
ApiGatewayV2CustomAuthorizerSimpleResponse::default();
output.is_authorized = true;
output.context = MyContext{some_thing_always_exists:Some(todo!("create a SomeThirdPartyThingWithoutDefaultValue")),};Ok(output)}/// An authorizer's response context which can be shared with another rust written lambda behind API Gateway.#[derive(Debug,Default,Serialize,Deserialize)]pubstructMyContext{// NOT IDEAL HERE://// Need to warp `SomeThirdPartyThingWithoutDefaultValue` with `Option` to fulfill `Default` requirement// or else cannot create a `ApiGatewayV2CustomAuthorizerSimpleResponse<MyContext>`.some_thing_always_exists:Option<SomeThirdPartyThingWithoutDefaultValue>,}
Consider this case, I guess force user rely on Default to initialize event has some limitation in type level. Maybe builder pattern can be a rescue? I'm not so sure.
++ to @ikai104 's use case, clearly we need an escape hatch.
I do think the builder approach COULD address this problem, but it would require a more complicated type state pattern to enforce that any field that does not have a default implementation, is required prior to finishing the builder.
Another option would be to add more ergonomic constructors similar to the ones that recently landed in: #1063
These would let us have constructors that specifically accept eg context without requiring it to implement Default, while still also using default for other fields.
A third option would be some sort of unstable_allow_struct_initialization feature, which we use to apply #[cfg_attr(not(feature="unstable_allow_struct_initialization"), non_exhaustive)]. In other words, we expose a feature that allows freeform struct initialization, and just relax any semver guarantees for that feature to allow breaking changes on struct fields across semver-compatible versions.
This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
Reopening since we are a ways off from releasing the new builder patterns (as we are in -rc territory still due to the managed instance feature being tested).
Also interested in whether the recently added builder pattern addresses your use cases @lmammino@ikai104@dcormier
(I'm working on getting a new release candidate out so that you can kick the tires...)
This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
Activity
jlizen commentedon Nov 17, 2025
Hi @dcormier , the intended API now when directly constructing would be to use
..Default::default()to guard against unknown fields. Does that work for you? I do think it would be good to have some examples demonstrating this...These were changed because it was constantly forcing semver bumps every update and was forcing consumers to either update their code or be frozen in time.
dcormier commentedon Nov 17, 2025
Modifying an existing rust example from AWS's docs to this:
Results in this:
Instead, you have to abandon struct literals entirely, which is less than ideal:
jlizen commentedon Nov 17, 2025
Ah, my mistake. This is running afoul of: rust-lang/lang-team#143 , which doesn't seem to have much traction.
It sounds like at minimum we should update the official example to compile properly (@PartiallyUntyped ).
But, agreed that abandoning struct literals is not ideal. This is an awkward situation, since we definitely can't maintain the library with reasonable stability without
#[non_exhaustive]Perhaps some sort of non-default feature flag like
features = ["experimental-non-exhaustive"]that has lesser semver guarantees?lmammino commentedon Nov 24, 2025
I’ve just run into the same issue and also found the current suggestion a bit unergonomic.
I’ve opened a proposal specifically for
SqsBatchResponsein #1063 that might (hopefully) offer a more ergonomic alternative.jeastham1993 commentedon Nov 25, 2025
Yep, encountered the same issue here. I agree with some of the previous comments, but I think the new way of building responses is not intuitive to use.
lmammino commentedon Nov 25, 2025
It might be a step forward, but I suspect the code might still be quite verbose in practice. It would be nice so see some examples for what you have in mind.
Is there an argument against crafting finely tuned utility functions like the ones proposed in #1063?
lmammino commentedon Nov 25, 2025
Thanks @PartiallyUntyped! 🙌🏽
Doesn't sound too bad, but what does building
batch_item_failureslook like?lmammino commentedon Nov 25, 2025
Looks pretty good to me! 🎉
Probably a little bit more verbose than what I am suggesting with #1063, but I get that this is probably more idiomatic (and easier to generate rather than having to write all of it manually)
lmammino commentedon Dec 2, 2025
I know it's re:Invent season and everyone is probably super busy with it but I am curious to know if there was any progress with the discussion here or any consideration given to #1063.
Thanks
jlizen commentedon Dec 2, 2025
Hey @lmammino , @PartiallyUntyped is currently OOO so the "codegenned automatic builders" will take some time.
Personally, it seems fine to me to also have custom, hand-written, even-more-ergonomic constructors for types where desired, such as #1063. Need to discuss with other maintainers but I'll at least give the PR a read-through in the meantime to reduce future churn.
(EDIT: Yeah, I got everybody's blessing to review #1063 as-is regardless of codegen plans)
ikai104 commentedon Dec 4, 2025
Share a use case:
Cannot create
ApiGatewayV2CustomAuthorizerSimpleResponse<MyContext>ifMyContexthas noDefault.Consider this case, I guess force user rely on
Defaultto initialize event has some limitation in type level. Maybe builder pattern can be a rescue? I'm not so sure.jlizen commentedon Dec 16, 2025
++ to @ikai104 's use case, clearly we need an escape hatch.
I do think the builder approach COULD address this problem, but it would require a more complicated type state pattern to enforce that any field that does not have a default implementation, is required prior to finishing the builder.
Another option would be to add more ergonomic constructors similar to the ones that recently landed in: #1063
These would let us have constructors that specifically accept eg
contextwithout requiring it to implementDefault, while still also using default for other fields.A third option would be some sort of
unstable_allow_struct_initializationfeature, which we use to apply#[cfg_attr(not(feature="unstable_allow_struct_initialization"), non_exhaustive)]. In other words, we expose a feature that allows freeform struct initialization, and just relax any semver guarantees for that feature to allow breaking changes on struct fields across semver-compatible versions.github-actions commentedon Feb 1, 2026
This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
jlizen commentedon Feb 2, 2026
Reopening since we are a ways off from releasing the new builder patterns (as we are in
-rcterritory still due to the managed instance feature being tested).Also interested in whether the recently added builder pattern addresses your use cases @lmammino @ikai104 @dcormier
(I'm working on getting a new release candidate out so that you can kick the tires...)
GradExMachina commentedon Feb 2, 2026
Perhaps the events library can be released by itself without a new RC?
jlizen commentedon Feb 2, 2026
Ah yeah, good point. Let me get the ball rolling on that.
dcormier commentedon Mar 31, 2026
@jlizen this does work for my purposes. Thanks to all involved.
jlizen commentedon Apr 2, 2026
The builders went out in aws_lambda_events@1.1.0.
github-actions commentedon Apr 2, 2026
This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.