bytebase/bytebase · error

failed to parse project from policy resource %q

Error message

failed to parse project from policy resource %q

What it means

ListProjectIamPolicies groups fetched policies by project. For each policy it calls common.GetProjectID(policy.Resource) to extract the project name from resource strings like "projects/123". errors.Wrapf(err, "failed to parse project from policy resource %q", policy.Resource) means a stored policy row's resource doesn't match the expected project resource format — usually a workspace-level policy (empty resource) or a malformed resource string leaked into the project-policy listing.

Source

Thrown at backend/store/policy.go:296

	for _, projectID := range projectIDs {
		resources = append(resources, common.FormatProject(projectID))
	}
	policies, err := s.ListPolicies(ctx, &FindPolicyMessage{
		Workspace:    workspaceID,
		ResourceType: new(storepb.Policy_PROJECT),
		Resources:    resources,
		Type:         new(storepb.Policy_IAM),
		ShowAll:      true,
	})
	if err != nil {
		return nil, err
	}

	policyMap := make(map[string]*storepb.IamPolicy, len(policies))
	for _, policy := range policies {
		projectID, err := common.GetProjectID(policy.Resource)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to parse project from policy resource %q", policy.Resource)
		}
		p := &storepb.IamPolicy{}
		if err := common.ProtojsonUnmarshaler.Unmarshal([]byte(policy.Payload), p); err != nil {
			return nil, errors.Wrapf(err, "failed to unmarshal iam policy for %v", policy.Resource)
		}
		policyMap[projectID] = p
	}
	return policyMap, nil
}

func (s *Store) GetWorkspaceIamPolicySnapshot(ctx context.Context, workspaceID string) (*IamPolicyMessage, error) {
	workspaceResource := common.FormatWorkspace(workspaceID)
	key := getIamPolicyCacheKey(workspaceID, storepb.Policy_WORKSPACE, workspaceResource)
	if v, ok := s.iamPolicyCache.Get(key); ok {
		return v, nil
	}
	return s.GetWorkspaceIamPolicy(ctx, workspaceID)
}

View on GitHub (pinned to 1870550677)

Solutions

  1. Inspect the offending policy row: check its resource value against the expected "projects/<id>" format.
  2. Fix the listing query filters so only IAM policies with project resources are returned (exclude workspace/empty-resource rows).
  3. Repair or delete malformed legacy policy rows; migrate resources that no longer parse.
  4. Harden the loop to skip non-project policies (log and continue) if mixed resources are legitimately possible.

Example fix

// before
projectID, err := common.GetProjectID(policy.Resource)
if err != nil {
	return nil, errors.Wrapf(err, "failed to parse project from policy resource %q", policy.Resource)
}
// after
projectID, err := common.GetProjectID(policy.Resource)
if err != nil {
	continue // skip non-project policies (e.g. workspace-level rows)
}
Defensive patterns

Strategy: fallback

Validate before calling

for _, p := range policies {
	if _, err := common.GetProjectID(p.Resource); err != nil {
		log.Printf("skipping non-project policy resource %q", p.Resource)
	}
}

Type guard

func isProjectPolicyResource(resource string) bool {
	_, err := common.GetProjectID(resource)
	return err == nil
}

Try / catch

policies, err := store.ListProjectIamPolicies(ctx)
if err != nil && strings.Contains(err.Error(), "failed to parse project from policy resource") {
	// corrupt/legacy row: log resource for repair and degrade gracefully
	return partialPoliciesWithWarning()
}

Prevention

When it happens

Trigger: GetProjectID fails on a policy returned by the underlying policy list during ListProjectIamPolicies: a workspace IAM policy row (resource not of form projects/<id>) is included by the query's filters, or a resource value with unexpected format/ID is present in the policy table.

Common situations: Legacy rows predating resource-format changes; a bug that stored the workspace policy with an unexpected resource; manual DB edits inserting policies with non-project resources; a filter regression in the listing query pulling in non-project policies.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/ad2f9a8a5e32f831. Report an issue: GitHub.