pulumi/pulumi · error

resource ID is required for lookup and cannot be empty

Error message

resource ID is required for lookup and cannot be empty

What it means

A resource lookup (readPackageResource, exposed via ctx.GetResource) requires the ID of the existing resource to look up. Passing a nil IDInput means there is nothing to search for, so the SDK errors immediately: "resource ID is required for lookup and cannot be empty". Lookups are read-only operations against the engine and are meaningless without an identifier.

Source

Thrown at sdk/go/pulumi/context.go:1377

// And invoke ReadPackageResource like so:
//
//	var resource MyResource
//	err := ctx.ReadPackageResource(tok, name, id, nil, &resource, opts...)
func (ctx *Context) ReadPackageResource(
	t, name string, id IDInput, props Input, resource CustomResource, packageRef string, opts ...ResourceOption,
) error {
	return ctx.readPackageResource(t, name, id, props, resource, packageRef, opts...)
}

func (ctx *Context) readPackageResource(
	t, name string, id IDInput, props Input, resource CustomResource, packageRef string, opts ...ResourceOption,
) error {
	if t == "" {
		return errors.New("resource type argument cannot be empty")
	} else if name == "" {
		return errors.New("resource name argument (for URN creation) cannot be empty")
	} else if id == nil {
		return errors.New("resource ID is required for lookup and cannot be empty")
	}

	if props != nil {
		propsType := reflect.TypeOf(props)
		if propsType.Kind() == reflect.Pointer {
			propsType = propsType.Elem()
		}
		//nolint:staticcheck // Not applying de-morgens law right now
		if !(propsType.Kind() == reflect.Struct ||
			(propsType.Kind() == reflect.Map && propsType.Key().Kind() == reflect.String)) {
			return errors.New("props must be a struct or map or a pointer to a struct or map")
		}
	}

	options := merge(opts...)
	parent := options.Parent
	if options.Parent == nil {
		options.Parent = ctx.state.stack

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Pass a concrete ID, e.g. ctx.GetResource(tok, name, pulumi.ID("i-abc123")) or the .ID() output of an existing resource reference.
  2. If the ID comes from an output, await/ensure it is non-nil before the lookup.
  3. If you don't know the ID, use ctx.GetResource with a provider-specific lookup or RegisterResource-style import instead.

Example fix

// before
var id pulumi.IDInput
res, err := ctx.GetResource("aws:ec2/instance:Instance", "web", id)
// after
res, err := ctx.GetResource("aws:ec2/instance:Instance", "web", pulumi.ID("i-0abcd1234efgh5678"))
Defensive patterns

Strategy: type-guard

Validate before calling

if id == nil {
    return fmt.Errorf("GetResource requires a non-nil ID")
}

Type guard

func hasID(id pulumi.IDInput) bool { return id != nil }

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "resource ID is required") {
        return fmt.Errorf("cannot look up %s: no ID available", name)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ctx.GetResource(token, name, nil), or passing an ID variable that is a nil pulumi.IDInput (zero value of an interface), e.g. an uninitialized *pulumi.String.

Common situations: Declaring `var id pulumi.IDInput` and forgetting to assign it; passing an output whose wrapped value is nil instead of an ID; converting code from RegisterResource (ID optional) to GetResource (ID required).

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/377536a424386dcf. Report an issue: GitHub.