Feature request: Helper function for validating required environment variables
Use case
It would be helpful to have a helper function to validate that required environment variables are present and not empty. This is a common use case when developing Lambda functions, and currently requires developers to write repetitive boilerplate code. This will improve error handling and make code more robust and maintainable.
Solution/User Experience
Create a helper function getRequiredEnvVar that:
- Takes the name of an environment variable as a parameter
- Checks if the variable exists and is not empty
- Returns the value if it exists
- Throws a descriptive error if the variable is missing or empty
Example Usage
import { getRequiredEnvVar } from '@aws-lambda-powertools/commons';
// Simple usage
const dbName = getRequiredEnvVar("DB_NAME");
// With type safety
const port = getRequiredEnvVar<number>("PORT", { parser: Number });
// Multiple variables for database configuration
const credentials = {
username: getRequiredEnvVar("DB_USER"),
password: getRequiredEnvVar("DB_PASS"),
host: getRequiredEnvVar("DB_HOST"),
port: getRequiredEnvVar<number>("DB_PORT", { parser: Number })
};
// Using with custom error message
const apiKey = getRequiredEnvVar("API_KEY", {
errorMessage: "API_KEY is required for external service integration"
});
Benefits
- Reduces boilerplate code
- Provides consistent error handling across applications
- Improves code readability
- Makes environment configuration issues more obvious during testing/deployment
- Follows the "fail fast" principle by validating configuration early
- Provides type safety and IntelliSense support in TypeScript projects
Implementation Notes
- Should be added to the
@aws-lambda-powertools/commonspackage - Type definition should support generic type parameter for type safety:
interface GetEnvVarOptions<T> {
parser?: (value: string) => T;
errorMessage?: string;
}
function getRequiredEnvVar<T = string>(
name: string,
options?: GetEnvVarOptions<T>
): T;
- Should throw a custom error type (e.g.,
MissingEnvironmentVariableError) for better error handling - Should trim whitespace from values before validation
- Empty strings should be considered invalid by default
- Consider adding validation for common types:
- Numbers (integers, floats)
- Booleans (true/false, yes/no, 1/0)
- JSON strings that need parsing
- Error messages should be clear and actionable, including:
- The name of the missing/invalid variable
- The expected format (if a parser was provided)
- Any custom error message provided in options
Alternative solutions
No response
Acknowledgment
- [x] This feature request meets Powertools for AWS Lambda (TypeScript) Tenets
- [x] Should this be considered in other Powertools for AWS Lambda languages? i.e. Python, Java, and .NET
Future readers
Please react with 👍 and your use case to help us understand customer demand.
Hey @garysassano , thanks for raising the issue. This is a common use case where you'd spend few lines of code to fetch and validate the environment variables that we could simplify and provide better error handling, especially for higher number of variables (10+).
The requirements and the solution remind me of https://github.com/ran-isenberg/aws-lambda-env-modeler from @ran-isenberg. Instead of calling getRequiredEnvVar multiple times, I see a better solution in having an environment object defined as a model. We could use zod parser to validate the model and also get a full error report for all environment variables.
const envSchema = z.object({
DB_NAME: z.string(),
DB_PORT: z.number(),
})
type MyEnvs = z.infer<typeof envSchema>;
const myEnvs: Myenvs = validateEnvs(envSchema)
const handler = async (event: unknown, context: Context) => {
// myEnvs is available, valid and typed here
}
The main benefit we could provide is 1/ fetch a list of variables from process.env, 2/ validate against pre-defined schema 3/ output full report on all variables.
I'd like to hear more feedback from the community and customers how they approach this problem and if it's worth implementing.
const envSchema = z.object({ DB_NAME: z.string(), DB_PORT: z.number(), })
type MyEnvs = z.infer<typeof envSchema>;
const myEnvs: Myenvs = validateEnvs(envSchema)
const handler = async (event: unknown, context: Context) => { // myEnvs is available, valid and typed here }
Personally I don't see what Powertools is adding here, if customers already have to provide their own schema, in the example envSchema, then they can just do this and achieve the same result:
const envSchema = z.object({
DB_NAME: z.string(),
DB_PORT: z.number(),
})
type MyEnvs = z.infer<typeof envSchema>;
const myEnvs: Myenvs = envSchema.parse(process.env);
const handler = async (event: unknown, context: Context) => {
// myEnvs is available, valid and typed here
}
I'm also not a huge fan of bringing in a 3rd party dependency to read environment variables, since in practice you can only store strings and the total size of all env variables, including keys, cannot exceed 4 KB. This limits quite a lot what you can or should store in the environment.
Having a getRequiredEnvVar with simple type coercion of the most basic types, i.e. string, number, boolean, Array of the previous three, and JSON could make sense, since in practice I'd see customers as well as myself using it the way Gary suggested and exporting my own config object that is shared across modules.
⚠️ COMMENT VISIBILITY WARNING ⚠️
This issue is now closed. Please be mindful that future comments 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.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
This is now released under v2.21.0 version!