anomalyco/sst · error · VisibleError
Cannot access `nodes.service` in dev mode.
Error message
Cannot access `nodes.service` in dev mode.
What it means
In SST's `Service` (v1) component, the `nodes` accessor object exposes raw Pulumi resources. During `sst dev`, the service runs as a live Lambda/container and the underlying `ecs.Service` Pulumi resource is not created, so `nodes.service` would be `undefined`. SST throws this `VisibleError` up front to give a clear message instead of a cryptic null dereference.
Source
Thrown at platform/src/components/aws/service-v1.ts:810
return this.devUrl;
}
if (!this._url) throw new VisibleError(errorMessage);
return this._url;
}
/**
* The underlying [resources](/docs/components/#nodes) this component creates.
*/
public get nodes() {
const self = this;
return {
/**
* The Amazon ECS Service.
*/
get service() {
if ($dev)
throw new VisibleError("Cannot access `nodes.service` in dev mode.");
return self.service!;
},
/**
* The Amazon ECS Task Role.
*/
get taskRole() {
return self.taskRole;
},
/**
* The Amazon ECS Task Definition.
*/
get taskDefinition() {
if ($dev)
throw new VisibleError(
"Cannot access `nodes.taskDefinition` in dev mode.",
);
return self.taskDefinition!;
},View on GitHub (pinned to a0bd20f762)
Solutions
- Wrap the `nodes.service` access in `if (!$dev) { ... }` so it only runs on deploy.
- Use the dev-mode alternatives the component provides (e.g. dev URL from `service.url`) instead of the raw resource.
- Split infrastructure references into a module only imported/executed at deploy time.
- If the reference is genuinely needed in dev, run `sst deploy --stage dev` instead of `sst dev` for that stack.
Example fix
// before
const svc = myService.nodes.service;
svc.name.apply((n) => grantAccess(n));
// after
if (!$dev) {
const svc = myService.nodes.service;
svc.name.apply((n) => grantAccess(n));
} Defensive patterns
Strategy: validation
Validate before calling
if ($dev) {
// skip nodes.service usage in dev
} else {
const svc = myService.nodes.service;
} Type guard
function canAccessNodes<T>(component: T): boolean {
return !($dev as boolean);
} Try / catch
try {
const svc = myService.nodes.service;
} catch (e) {
if (e instanceof VisibleError && e.message.includes("dev mode")) return null;
throw e;
} Prevention
- Always wrap `nodes.*` accesses in `if (!$dev)` checks.
- Prefer component-level APIs (`service.url`) over raw Pulumi nodes.
- Centralize deploy-only wiring in helper functions that assert non-dev.
When it happens
Trigger: Calling `service.nodes.service` while running `sst dev` (i.e. `$dev` is true). Any code path that reads the ECS Service resource from the nodes getter during the dev loop triggers it.
Common situations: Developers wiring an ECS Service to another component (e.g. granting IAM permissions or referencing the service ARN) in code that also runs during dev mode; following examples/docs that use `nodes` without dev-mode guards.
Related errors
- Cannot access `nodes.taskDefinition` in dev mode.
- Cannot access `nodes.loadBalancer` in dev mode.
- Cannot access `nodes.loadBalancer` when no public ports are
- The ALB VPC "${albVpcId}" does not match the cluster VPC "${
- Request count scaling is only supported for http/https proto
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/7fdd240493f301b7.
Report an issue: GitHub.