pulumi/pulumi · error

unclosed string [%s

Error message

unclosed string [%s

What it means

For quoted string keys ('["key"]'), parseIndex scans for the closing double quote. If the input ends before a '"' is found, the string (and the bracket) was never terminated; the error echoes the entire remaining input, e.g. 'unclosed string ["abc'.

Source

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

				break
			}
		}
		if len(runes) < i || runes[i] != ']' {
			return nil, nil, fmt.Errorf("unclosed index [%s", string(runes[:i]))
		}
		n, err := strconv.ParseUint(string(runes[0:i]), 10, 64)
		if err != nil {
			return nil, nil, err
		}
		if n > math.MaxInt64 {
			return nil, nil, fmt.Errorf("indexes cannot exceed %d", int64(math.MaxInt64))
		}
		return IndexSegment{n}, runes[i+1:], nil
	case runes[0] == '"':
		i := 1
		for ; ; i++ {
			if len(runes) <= i {
				return nil, nil, fmt.Errorf(`unclosed string [%s`, string(runes))
			}
			if runes[i] == '"' {
				if len(runes) <= i+1 || runes[i+1] != ']' {
					return nil, nil, fmt.Errorf(`unclosed index [%s`, string(runes[:i+1]))
				}
				key, err := strconv.Unquote(string(runes[:i+1]))
				return KeySegment{key}, runes[i+2:], err
			}
			if runes[i] == '\\' {
				i++
			}
		}
	case runes[0] == '*':
		if len(runes) == 1 || runes[1] != ']' {
			return nil, nil, errors.New(`expected ']' after "[*"`)
		}
		return Splat, runes[2:], nil
	default:

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Close the quoted key with '"' and the bracket with ']': `arr["key"]`.
  2. Build the quoted segment with %q or strconv.Quote rather than hand-concatenating quotes.
  3. Check for a trailing backslash that escapes the closing quote and double it if a literal backslash is intended.

Example fix

// before
err := g.UnmarshalText([]byte(`arr["key`)) // unclosed string ["key
// after
err := g.UnmarshalText([]byte(`arr["key"]`))
// or build safely
quoted := fmt.Sprintf("arr[%s]", strconv.Quote("key"))
err := g.UnmarshalText([]byte(quoted))
Defensive patterns

Strategy: validation

Validate before calling

re := regexp.MustCompile(`^\["(?:[^"\\]|\\.)*"\]$`)
for _, m := range bracketRe.FindAllString(globStr, -1) {
	if strings.HasPrefix(m, `["`) && !re.MatchString(m) {
		return fmt.Errorf("malformed quoted key segment %q", m)
	}
}

Try / catch

var g property.Glob
if err := g.UnmarshalText([]byte(globStr)); err != nil {
	return fmt.Errorf("cannot parse glob %q: %w", globStr, err)
}

Prevention

When it happens

Trigger: UnmarshalText with input like `arr["key` or `arr["key\\` (trailing backslash escapes the end as the loop skips one char) — the closing quote never appears before end of input.

Common situations: Manually building quoted keys without strconv.Quote, truncation during serialization, or escaping mistakes where a stray backslash swallows the closing quote.

Related errors


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