anomalyco/sst · error · VisibleError
Cannot access `nodes.taskDefinition` in dev mode.
Error message
Cannot access `nodes.taskDefinition` in dev mode.
What it means
The Service component's `nodes` getter exposes raw Pulumi resources it creates. In `sst dev` mode the Service runs as a live dev process against the cluster and the ECS Task Definition resource is never created, so accessing `nodes.taskDefinition` would return `undefined`. SST throws this VisibleError to fail fast instead of letting downstream code operate on a missing resource.
Source
Thrown at platform/src/components/aws/service.ts:2898
get service() {
if (self.dev)
throw new VisibleError("Cannot access `nodes.service` in dev mode.");
return self._service!;
},
/**
* The Amazon ECS Execution Role.
*/
executionRole: this.executionRole,
/**
* The Amazon ECS Task Role.
*/
taskRole: this.taskRole,
/**
* The Amazon ECS Task Definition.
*/
get taskDefinition() {
if (self.dev)
throw new VisibleError(
"Cannot access `nodes.taskDefinition` in dev mode.",
);
return self.taskDefinition!;
},
/**
* The Amazon Elastic Load Balancer.
*/
get loadBalancer() {
if (self.dev)
throw new VisibleError(
"Cannot access `nodes.loadBalancer` in dev mode.",
);
if (!self.loadBalancer)
throw new VisibleError(
"Cannot access `nodes.loadBalancer` when no public ports are exposed.",
);
return self.loadBalancer;
},View on GitHub (pinned to a0bd20f762)
Solutions
- Do not read `nodes.taskDefinition` when the app is in dev mode; gate the access with `$dev` (from `sst/dev`) so the code only runs on deploy.
- If you need the resource only for deployment-time wiring, move that logic behind `if (!$dev) { ... }` and provide a dev-mode alternative.
- Run `sst deploy` (not `sst dev`) for the workflow that requires the underlying Task Definition.
Example fix
// before
const td = service.nodes.taskDefinition;
// after
import { $dev } from "sst/dev";
const td = $dev ? undefined : service.nodes.taskDefinition; Defensive patterns
Strategy: validation
Validate before calling
import { $dev } from "sst/dev";
if (!$dev) {
const td = service.nodes.taskDefinition; // safe on deploy
} Type guard
import { $dev } from "sst/dev";
const hasTaskDefinition = (): boolean => !$dev; Try / catch
import { VisibleError } from "sst/platform/src/components/error"; // conceptual
try {
const td = service.nodes.taskDefinition;
} catch (e) {
if (String(e).includes("in dev mode")) {
// dev-mode fallback: skip task-definition wiring
} else throw e;
} Prevention
- Never read `nodes.*` unconditionally in sst.config.ts; always consider dev mode.
- Use `$dev` from `sst/dev` to branch deploy-only resource wiring.
- Test configs under both `sst dev` and `sst deploy` before committing.
- Prefer the component's public API/links over raw nodes when available.
When it happens
Trigger: Reading `service.nodes.taskDefinition` in an sst.config.ts while `sst dev` is running (i.e. `sst dev` with a Service component configured, or `dev.command` set so the component is in dev mode).
Common situations: Referencing `nodes.taskDefinition` to build an IAM policy, log group attachment, or custom ECS resource that unconditionally reads the property; the same sst.config.ts works on `sst deploy` but crashes under `sst dev` because dev mode is environment-dependent.
Related errors
- Cannot access `nodes.service` in dev mode.
- Cannot access `nodes.taskDefinition` in dev mode.
- Cannot access `nodes.loadBalancer` in dev mode.
- Cannot access `nodes.loadBalancer` in dev mode.
- Cannot access `nodes.autoScalingTarget` in dev mode.
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/23d12ad549a5fda3.
Report an issue: GitHub.