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
- Run `sst secret set MySecret <value>` (with the current `--stage` if needed), then redeploy.
- Set a placeholder in code if the value is not sensitive: `new sst.Secret("MySecret", "fallback-value")`.
- For PR/preview stages, set a fallback value: `sst secret set MySecret <value> --fallback`.
- Verify the exact secret name matches everywhere — names are case-sensitive for the SST_SECRET_<NAME> env var lookup.
- 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
- Run `sst secret set <Name> <value>` for every stage before deploying
- Use `--fallback` for values shared by PR/preview stages
- Pass a placeholder argument when the value is not sensitive
- Keep secret names in a constants file to avoid case-sensitive typos
- Document required secrets in CI setup so pipelines set them before deploy
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
- Invalid function definition for the "${name}" Function
- Cannot access `nodes.loadBalancer` when no public ports are
- You must provide the ports to expose via "loadBalancer.rules
- You must provide a container name in "loadBalancer.rules" wh
- Invalid rule conditions for listen protocol "${v.listen}". O
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/c0ea13638cc3c14a.
Report an issue: GitHub.