Pulumi Error: 'Cannot read properties of undefined (reading apply)' — Cause, Fix, and Troubleshooting Guide
Fix Pulumi TypeError: Cannot read properties of undefined (reading 'apply') in TypeScript — Output ordering, undefined values, and misordered imports.
- #pulumi
- #iac
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
TypeError: Cannot read properties of undefined (reading 'apply') is a plain JavaScript/TypeScript runtime error that surfaces inside your Pulumi program: you called .apply(...) on something that is undefined. Pulumi’s Node.js language host runs your code, so this throws while the program executes and usually appears wrapped in Running program ... failed with an unhandled exception.
The word apply is the tell: .apply() is the method you call on a Pulumi Output<T> to transform its eventual value. Getting this error almost always means you thought you had an Output, but the variable was actually undefined — because a resource property doesn’t exist, a value hasn’t been assigned yet, a function returned nothing, or a module import resolved to undefined.
error: Running program '/app' failed with an unhandled exception:
TypeError: Cannot read properties of undefined (reading 'apply')
at /app/index.ts:37:28
Symptoms
- Deployment fails with
Cannot read properties of undefined (reading 'apply')and a stack frame in your own.ts/.jsfile. - The line at fault contains a
.apply(...)(or.applyis passed as a callback reference). - The variable you called
.apply()on isundefinedat that moment — a resource output, a helper return value, or an import. - Adding a
console.logjust before the line printsundefinedfor that variable.
Common Root Causes
1. Accessing a property that doesn’t exist on a resource
You reference an output field the resource doesn’t actually expose (typo, wrong resource type, or a field that only exists on inputs). The property is undefined, so .apply() on it throws.
const bucket = new aws.s3.BucketV2("data", {});
// Typo: it's `bucket`, not `bucketName`, on BucketV2 — `bucketName` is undefined.
export const name = bucket.bucketName.apply(n => n.toUpperCase());
2. A helper function that forgets to return
A factory/component helper that builds a resource but returns nothing yields undefined; calling .apply() on the result fails.
function makeVpc(name: string) {
const vpc = new aws.ec2.Vpc(name, { cidrBlock: "10.0.0.0/16" });
// Oops — no return statement.
}
const vpc = makeVpc("main");
export const vpcId = vpc.id.apply(id => id); // vpc is undefined
3. Misordered or circular imports leaving a value undefined
If module A imports from module B and B (transitively) imports A, one side can see a not-yet-initialized (undefined) export at the moment your code runs. The exported resource/output is undefined when you touch it.
// network.ts imports from app.ts and vice-versa; at runtime `sharedVpc`
// may still be undefined depending on which module loaded first.
import { sharedVpc } from "./network";
export const id = sharedVpc.id.apply(x => x); // sharedVpc undefined
4. Treating a plain value as an Output (or vice-versa)
Calling .apply() on a plain string/number (which has no .apply) — or on a variable you never assigned — throws. Plain values don’t have .apply; only Output<T> does.
5. An awaited value that resolved to undefined
An async data source that returned nothing (bad filter, no match) leaves you with undefined, then .apply() fails.
How to Diagnose
Pinpoint the exact line and inspect the variable’s real value.
# Re-run with a stack trace so the failing file:line is explicit.
pulumi up --logtostderr -v=3 2> pulumi-debug.log
# Type-check independently — many of these are catchable statically.
npx tsc --noEmit
// Add a temporary guard/log right above the failing line.
console.error("DEBUG bucket =", bucket, "bucketName =", (bucket as any)?.bucketName);
# Confirm the correct property names for the resource you use.
# The Pulumi Registry docs list outputs vs inputs per resource type.
# e.g. aws.s3.BucketV2 exposes `bucket`, `arn`, `id` as outputs.
grep -n "\.apply(" index.ts # find every apply call to audit
Fixes
Use the correct output property name: Check the resource’s outputs in the Pulumi Registry and reference the real field. For aws.s3.BucketV2, the bucket name output is bucket, not bucketName.
const bucket = new aws.s3.BucketV2("data", {});
export const name = bucket.bucket.apply(n => n.toUpperCase()); // fixed
Return values from helper functions: Make sure every factory returns the resource (or an object of outputs) you later use.
function makeVpc(name: string) {
const vpc = new aws.ec2.Vpc(name, { cidrBlock: "10.0.0.0/16" });
return vpc; // ← the fix
}
const vpc = makeVpc("main");
export const vpcId = vpc.id;
Break circular imports: Move the shared resource into its own leaf module that both sides import, so there is no cycle and the export is always initialized before use.
// shared.ts (no imports back into app/network)
export const sharedVpc = new aws.ec2.Vpc("shared", { cidrBlock: "10.0.0.0/16" });
Guard undefined values and prefer pulumi.output: When a value may be absent, validate it, or normalize plain values into Outputs with pulumi.output(...) so .apply() is always valid.
import * as pulumi from "@pulumi/pulumi";
// Normalize: works whether `maybeName` is a string or an Output<string>.
const nameOut = pulumi.output(maybeName ?? "default-name");
export const upper = nameOut.apply(n => n.toUpperCase());
Combine multiple outputs safely with pulumi.all: If you were reaching across several resources, use pulumi.all([...]).apply(...) instead of chaining on a possibly-undefined single value.
export const conn = pulumi
.all([db.address, db.port])
.apply(([host, port]) => `postgres://${host}:${port}/app`);
What to Watch Out For
.applyonly exists onOutput<T>— if you need it and it’s missing, the value isundefinedor a plain type; wrap it withpulumi.output(...).- Resource input property names often differ from output names; always check the Registry outputs list.
npx tsc --noEmitcatches many of these (unknown property, possibly-undefined) before deploy — run it in CI.- Circular imports are sneaky: the failure depends on load order and can appear intermittently.
- Don’t reach into
output.value— there is no such synchronous accessor; use.apply()orpulumi.all().
Related Guides
- Pulumi Error: ‘Running program failed with an unhandled exception’ — Troubleshooting Guide
- Pulumi Error: ‘could not find any node_modules folder’ — Troubleshooting Guide
- Pulumi Error: ‘preview failed’ — Troubleshooting Guide
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.