From 04781e1f96919fd6b0681fe1d414898a6f40a6e0 Mon Sep 17 00:00:00 2001 From: TobiasMaehl-pIX Date: Thu, 22 Jan 2026 23:43:24 +0100 Subject: [PATCH 1/2] fix(sst): don't override envs with empty bind values --- .changeset/hip-steaks-share.md | 5 +++++ packages/sst/src/cli/commands/bind.ts | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 .changeset/hip-steaks-share.md diff --git a/.changeset/hip-steaks-share.md b/.changeset/hip-steaks-share.md new file mode 100644 index 000000000..5cd59183b --- /dev/null +++ b/.changeset/hip-steaks-share.md @@ -0,0 +1,5 @@ +--- +"sst": patch +--- + +Fix sst bind to skip empty env vars so local env values aren’t overwritten diff --git a/packages/sst/src/cli/commands/bind.ts b/packages/sst/src/cli/commands/bind.ts index f5f8f3d50..d423bfd04 100644 --- a/packages/sst/src/cli/commands/bind.ts +++ b/packages/sst/src/cli/commands/bind.ts @@ -204,7 +204,7 @@ export const bind = (program: Program) => (await getLiveIamCredentials(siteConfig.role))) || (await getLocalIamCredentials()); await runCommand({ - ...siteConfig.envs, + ...stripEmptyEnvValues(siteConfig.envs), ...credentials, }); } @@ -228,7 +228,7 @@ export const bind = (program: Program) => const { Config } = await import("../../config.js"); await runCommand({ - ...constructEnvs, + ...stripEmptyEnvValues(constructEnvs), ...(await Config.env()), ...(await getLocalIamCredentials()), }); @@ -242,6 +242,15 @@ export const bind = (program: Program) => }); } + function stripEmptyEnvValues(envs) { + return Object.fromEntries( + Object.entries(envs).filter( + ([, value]) => + value !== undefined && value !== null && value !== "" + ) + ); + } + async function getSsrSiteMetadata() { const [ { metadataForStack }, From 629e75ff4ca01a2194721c4447017b206701ec26 Mon Sep 17 00:00:00 2001 From: TobiasMaehl-pIX Date: Fri, 23 Jan 2026 00:09:38 +0100 Subject: [PATCH 2/2] fix(bind): improve stripEmptyEnvValues function --- packages/sst/src/cli/commands/bind.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/sst/src/cli/commands/bind.ts b/packages/sst/src/cli/commands/bind.ts index d423bfd04..8dc0226df 100644 --- a/packages/sst/src/cli/commands/bind.ts +++ b/packages/sst/src/cli/commands/bind.ts @@ -14,8 +14,8 @@ type BIND_REASON = | "secrets_updated" | "iam_expired"; -class MetadataNotFoundError extends Error {} -class MetadataOutdatedError extends Error {} +class MetadataNotFoundError extends Error { } +class MetadataOutdatedError extends Error { } export const bind = (program: Program) => program @@ -183,8 +183,8 @@ export const bind = (program: Program) => const siteConfig = ssrSite ? await getSsrSiteMetadata() : staticSite - ? await getStaticSiteMetadata() - : await getServiceMetadata(); + ? await getStaticSiteMetadata() + : await getServiceMetadata(); // Handle rebind due to metadata updated if (reason === "metadata_updated") { @@ -242,13 +242,16 @@ export const bind = (program: Program) => }); } - function stripEmptyEnvValues(envs) { - return Object.fromEntries( - Object.entries(envs).filter( - ([, value]) => - value !== undefined && value !== null && value !== "" - ) - ); + function stripEmptyEnvValues( + envs: Record | undefined + ): Record { + const result: Record = {}; + for (const [key, value] of Object.entries(envs ?? {})) { + if (value !== undefined && value !== null && value !== "") { + result[key] = value; + } + } + return result; } async function getSsrSiteMetadata() {