pulumi/pulumi · error

cannot marshal an empty glob

Error message

cannot marshal an empty glob

What it means

property.Glob implements encoding.TextMarshaler; marshaling a Glob that has zero segments (the zero value Glob{}) is rejected because an empty string is not a valid property-path glob representation. The method returns this error instead of emitting an empty byte slice.

Source

Thrown at sdk/go/property/glob.go:42

	"strings"

	"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
)

type Glob struct{ pathRepr }

func GlobFromSegments(segments ...GlobSegment) Glob {
	return Glob{pathReprFromSegments(segments)}
}

var (
	_ encoding.TextMarshaler   = Glob{}
	_ encoding.TextUnmarshaler = &Glob{}
)

func (g Glob) MarshalText() (text []byte, err error) {
	if g.len() == 0 {
		return nil, errors.New("cannot marshal an empty glob")
	}
	var b strings.Builder
segment:
	for i, p := range g.enumerate {
		switch p := p.(type) {
		case KeySegment:
			bare := len(p.string) > 0
			for j, c := range p.string {
				if !isPlainPathCharacter(c, j == 0) {
					bare = false
					break
				}
			}
			if !bare {
				fmt.Fprintf(&b, "[%q]", p.string)
				continue segment
			}
			if i != 0 {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Ensure the Glob has at least one segment before marshaling: use GlobFromSegments with at least one KeySegment, IndexSegment, or GlobAll segment.
  2. Guard with a check before encoding: skip or substitute a default glob when the value is the zero Glob.
  3. Use a pointer field (*Glob) with nil to represent 'absent' instead of an empty glob.

Example fix

// before
g := property.GlobFromSegments() // empty
b, err := g.MarshalText()         // error
// after
g := property.GlobFromSegments(property.Key("foo"), property.GlobAll{})
b, err := g.MarshalText()
Defensive patterns

Strategy: validation

Validate before calling

func marshalGlobSafe(g property.Glob) ([]byte, error) {
	if g == (property.Glob{}) {
		return nil, fmt.Errorf("glob not initialized")
	}
	return g.MarshalText()
}

Type guard

func isZeroGlob(g property.Glob) bool { return g == property.Glob{} }

Try / catch

text, err := g.MarshalText()
if err != nil {
	if err.Error() == "cannot marshal an empty glob" {
		// substitute default or skip field
	}
	return err
}

Prevention

When it happens

Trigger: Calling Glob.MarshalText() (directly or via encoding/json, yaml, or other TextMarshaler-aware encoders) on a Glob constructed with GlobFromSegments() with no arguments or a zero-value Glob{}.

Common situations: Serializing a struct field of type Glob that was never initialized; decoding failures upstream that left the glob empty; building segments conditionally and ending up with none.

Related errors


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