pulumi/pulumi · error

failed to load Pulumi policy project located at %q: %w

Error message

failed to load Pulumi policy project located at %q: %w

What it means

When launching a policy analyzer plugin, the PulumiPolicy.yaml in the given policy pack directory is loaded first. If loading that project file fails (missing file, invalid YAML, schema violation), the error is wrapped with the pack path.

Source

Thrown at sdk/go/common/resource/plugin/analyzer_plugin.go:112

	return &analyzer{
		name:   name,
		plug:   plug,
		client: pulumirpc.NewAnalyzerClient(plug.Conn),
	}, nil
}

// NewPolicyAnalyzer boots the analyzer plugin located at `policyPackpath`. `hasPlugin` is a function that allows the
// caller to configure how it is determined if the language plugin is available. If nil it will default to looking for
// the plugin by path.
func NewPolicyAnalyzer(
	host Host, ctx *Context, name tokens.QName, policyPackPath string, opts *PolicyAnalyzerOptions,
	hasPlugin func(workspace.PluginDescriptor) bool,
) (Analyzer, error) {
	projPath := filepath.Join(policyPackPath, "PulumiPolicy.yaml")
	proj, err := workspace.LoadPolicyPack(projPath)
	if err != nil {
		return nil, fmt.Errorf("failed to load Pulumi policy project located at %q: %w", policyPackPath, err)
	}

	handshake := func(
		ctx context.Context, bin string, prefix string, conn *grpc.ClientConn,
	) (*pulumirpc.AnalyzerHandshakeResponse, error) {
		// For analyzers the root directory and program directory are the location of the PulumiPolicy.yaml _not_ the
		// location of the shim plugin.
		dir := policyPackPath
		client := pulumirpc.NewAnalyzerClient(conn)

		req := pulumirpc.AnalyzerHandshakeRequest{
			EngineAddress:    host.ServerAddr(),
			RootDirectory:    &dir,
			ProgramDirectory: &dir,
		}

		res, err := client.Handshake(ctx, &req)
		if err != nil {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Verify the path points to a directory containing a valid PulumiPolicy.yaml
  2. Validate the YAML syntax and required fields (runtime, etc.) in PulumiPolicy.yaml
  3. Re-create or re-checkout the policy pack if the file was deleted

Example fix

// before
pulumi up --policy-pack ./not-a-pack
// after
cd ./my-policy-pack && ls PulumiPolicy.yaml && pulumi up --policy-pack .
Defensive patterns

Strategy: validation

Validate before calling

projPath := filepath.Join(packDir, "PulumiPolicy.yaml")
if _, err := os.Stat(projPath); err != nil {
    return fmt.Errorf("%s is not a policy pack: missing PulumiPolicy.yaml", packDir)
}

Type guard

null

Try / catch

analyzer, err := plugin.NewPolicyAnalyzer(host, ctx, name, packPath, opts, hasPlugin)
if err != nil {
    if strings.Contains(err.Error(), "failed to load Pulumi policy project") {
        // check PulumiPolicy.yaml exists and is valid YAML
    }
}

Prevention

When it happens

Trigger: Calling NewPolicyAnalyzer (or NewAnalyzer with a policyPackPath) where <policyPackPath>/PulumiPolicy.yaml does not exist or fails workspace.LoadPolicyPack validation.

Common situations: Running pulumi up with --policy-pack pointing at a directory that is not a policy pack; typo'd path; PulumiPolicy.yaml renamed or malformed after editing.

Related errors


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