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
- Inspect the offending policy row: check its resource value against the expected "projects/<id>" format.
- Fix the listing query filters so only IAM policies with project resources are returned (exclude workspace/empty-resource rows).
- Repair or delete malformed legacy policy rows; migrate resources that no longer parse.
- 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
- Filter policy queries to resource LIKE 'projects/%' before parsing
- Skip-and-log unexpected resources instead of failing the whole listing
- Migrate legacy rows whose resource format changed
- Add a data-integrity check for policy resource formats
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Another chat is already using a page-changing tool. Wait for
- Database is required for update
- policy type is required
- common.error
- this Elasticsearch API is not supported when data masking is
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/ad2f9a8a5e32f831.
Report an issue: GitHub.