pulumi/pulumi · error

'%s' must be of type string

Error message

'%s' must be of type string

What it means

GetProviderParameterization reads '__internal.parameterization', a base64-encoded string encoding the provider's parameterization spec, and requires it to be a string. The engine throws this when the value is a non-string type, since the base64 payload can only be carried as a string.

Source

Thrown at pkg/resource/deploy/providers/registry.go:322

}

// GetProviderParameterization fetches and parses a provider parameterization from the given property map. If the
// parameterization property is not present, this function returns nil.
func GetProviderParameterization(
	name tokens.Package, inputs resource.PropertyMap,
) (*workspace.Parameterization, error) {
	internalInputs, err := getInternal(inputs)
	if err != nil {
		return nil, err
	}

	parameter, ok := internalInputs[parameterizationKey]
	if !ok {
		return nil, nil
	}

	if !parameter.IsString() {
		return nil, fmt.Errorf("'%s' must be of type string", parameterizationKey)
	}
	bytes, err := base64.StdEncoding.DecodeString(parameter.StringValue())
	if err != nil {
		return nil, fmt.Errorf("could not decode base64 parameter value: %w", err)
	}

	version, ok := inputs["version"]
	if !ok {
		return nil, errors.New("must have a 'version' field")
	}
	if !version.IsString() {
		return nil, errors.New("must have a 'version' field of type string")
	}
	sv, err := semver.Parse(version.StringValue())
	if err != nil {
		return nil, fmt.Errorf("could not parse provider version: %w", err)
	}

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Restore __internal.parameterization to its base64 string form (as written when the provider was created) via stack export/import
  2. Remove the parameterization key only if the provider truly is not parameterized — otherwise recreate the provider resource
  3. Regenerate the base64 value from the correct parameterization spec and write it back as a string
  4. Upgrade the CLI/provider if a version mismatch rewrote state incorrectly

Example fix

// before
"__internal": { "parameterization": { "name": "aws", "version": "1.0.0" } }
// after
"__internal": { "parameterization": "eyJuYW1lIjoiYXdzIiwidmVyc2lvbiI6IjEuMC4wIn0=" }
Defensive patterns

Strategy: type-guard

Validate before calling

if p, ok := internalInputs["parameterization"]; ok && !p.IsString() {
	return fmt.Errorf("parameterization must be a base64 string, got %s", p.TypeString())
}

Type guard

func isBase64String(v resource.PropertyValue) bool {
	if !v.IsString() { return false }
	_, err := base64.StdEncoding.DecodeString(v.StringValue())
	return err == nil
}

Prevention

When it happens

Trigger: __internal.parameterization is a number, bool, array, or object in the provider's inputs, typically from corrupted or hand-modified state.

Common situations: Hand-edited state; tooling or migrations that re-encoded the base64 blob into another type; custom parameterized-provider code writing raw objects instead of encoding to base64.

Related errors


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