Describe the bug
ImplicitApiPlugin._add_tags_to_implicit_api_if_necessary() decides whether to copy a resource's Tags onto its generated implicit AWS::Serverless::Api/HttpApi resource using:
should_propagate_tags = resource.properties.get("PropagateTags") or globals_var.get("PropagateTags")
PropagateTags is documented as bool | None (see samtranslator/internal/schema_source/aws_serverless_function.py), where None means "not set" and False is a meaningful, explicit opt-out. Using or means a local PropagateTags: false is indistinguishable from "not set" — it silently falls through to the global value.
Reproduction
Globals:
Function:
PropagateTags: true
Tags:
Team: Data
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
PropagateTags: false # explicit opt-out
Runtime: python3.12
Handler: index.handler
CodeUri: s3://bucket/key
Events:
Api:
Type: Api
Properties:
Path: /hello
Method: get
Expected behavior
The function explicitly disables PropagateTags, so the generated implicit AWS::Serverless::Api should NOT receive the Team: Data tag.
Actual behavior
resource.properties.get("PropagateTags") returns False (falsy), so or evaluates the global value (True) instead, and the tag is propagated to the implicit API anyway — silently ignoring the resource-level override.
This is inconsistent with the standard Globals merge logic (GlobalProperties._prefer_local in samtranslator/plugins/globals/globals.py), which always prefers the local value when the key is present locally, regardless of its truthiness.
Fix
PR incoming.
Describe the bug
ImplicitApiPlugin._add_tags_to_implicit_api_if_necessary()decides whether to copy a resource'sTagsonto its generated implicitAWS::Serverless::Api/HttpApiresource using:PropagateTagsis documented asbool | None(seesamtranslator/internal/schema_source/aws_serverless_function.py), whereNonemeans "not set" andFalseis a meaningful, explicit opt-out. Usingormeans a localPropagateTags: falseis indistinguishable from "not set" — it silently falls through to the global value.Reproduction
Expected behavior
The function explicitly disables
PropagateTags, so the generated implicitAWS::Serverless::Apishould NOT receive theTeam: Datatag.Actual behavior
resource.properties.get("PropagateTags")returnsFalse(falsy), soorevaluates the global value (True) instead, and the tag is propagated to the implicit API anyway — silently ignoring the resource-level override.This is inconsistent with the standard Globals merge logic (
GlobalProperties._prefer_localinsamtranslator/plugins/globals/globals.py), which always prefers the local value when the key is present locally, regardless of its truthiness.Fix
PR incoming.