anomalyco/sst · error · SecretMissingError

${this._name}

Error message

${this._name}

What it means

`Secret` resolves its value from the `SST_SECRET_<NAME>` environment variable injected by SST, falling back to the optional `placeholder` argument. If neither exists, the resolved value is undefined and the constructor throws `SecretMissingError`, which tells you to run `sst secret set <Name> <value>`.

Source

Thrown at platform/src/components/secret.ts:126

   * @param placeholder A placeholder value of the secret. This can be useful for cases where you might not be storing sensitive values.

   */
  constructor(name: string, placeholder?: Input<string>) {
    super(
      "sst:sst:Secret",
      name,
      {
        placeholder,
      },
      {},
    );
    this._name = name;
    this._placeholder = placeholder !== undefined ? output(placeholder) : undefined;
    this._value = output(
      process.env["SST_SECRET_" + this._name] ?? this._placeholder,
    ).apply((value) => {
      if (typeof value !== "string") {
        throw new SecretMissingError(this._name);
      }
      return value;
    });
  }

  /**
   * The name of the secret.
   */
  public get name() {
    return output(this._name);
  }

  /**
   * The value of the secret. It'll be `undefined` if the secret has not been set through the CLI or if the `placeholder` hasn't been set.
   */
  public get value() {
    return secret(this._value);
  }

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Run `sst secret set MySecret <value>` (with the current `--stage` if needed), then redeploy.
  2. Set a placeholder in code if the value is not sensitive: `new sst.Secret("MySecret", "fallback-value")`.
  3. For PR/preview stages, set a fallback value: `sst secret set MySecret <value> --fallback`.
  4. Verify the exact secret name matches everywhere — names are case-sensitive for the SST_SECRET_<NAME> env var lookup.
  5. In CI, ensure secrets are set for that stage (or use the fallback) before running `sst deploy`.

Example fix

// before
const secret = new sst.Secret("StripeKey");
// after (set the value first)
//   sst secret set StripeKey sk_live_... --fallback
const secret = new sst.Secret("StripeKey");
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing the Secret, check it has been set
const name = "StripeKey";
if (!process.env[`SST_SECRET_${name}`]) {
  throw new Error(`Run: sst secret set ${name} <value> (or pass a placeholder)`);
}
const secret = new sst.Secret(name);

Type guard

function hasSecret(name: string): boolean {
  return typeof process.env[`SST_SECRET_${name}`] === "string";
}

Try / catch

try {
  const secret = new sst.Secret("StripeKey");
} catch (e) {
  if (String(e).includes("sst secret set")) {
    console.error("Secret StripeKey is unset for this stage. Run: sst secret set StripeKey <value>");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `new sst.Secret("MySecret")` with no placeholder while the secret has never been set via `sst secret set` (no `SST_SECRET_MySecret` env var is present in the deploy process). Also occurs in CI/PR stages where the secret has no stage value and no `--fallback` was set.

Common situations: Fresh machine or CI environment missing `sst secret set` for the current stage; deploying a PR/preview stage that has no secret value and no fallback; typo in the secret name so SST injects a different env var; forgetting the placeholder argument during local-first development.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/c0ea13638cc3c14a. Report an issue: GitHub.