goharbor/harbor · error

no such Retention policy with id

Error message

no such Retention policy with id %v

What it means

Not-found mapping in DefaultManager.GetPolicy: when the DAO returns orm.ErrNoRows for the requested policy ID, it is translated into this explicit 'no such Retention policy' error so callers do not see a raw ORM sentinel. It fires whenever the ID does not exist in the retention policy table (deleted, never created, or wrong ID).

Solutions

  1. Verify the policy ID via the retention API list endpoint before fetching it individually
  2. Confirm the policy was not deleted by another user or a concurrent operation
  3. Treat this error as a 404 condition in API layers and surface it as not-found to the client
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/pkg/retention/manager.go:91 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/dd69432b4ed21089. Report an issue: GitHub.

Appendix: source

Thrown at src/pkg/retention/manager.go:91

	p.ID = 0
	data, _ := json.Marshal(p)
	p.ID = p1.ID
	p1.Data = string(data)
	p1.UpdateTime = time.Now()
	return dao.UpdatePolicy(ctx, p1, "scope_level", "trigger_kind", "data", "update_time")
}

// DeletePolicy Delete Policy
func (d *DefaultManager) DeletePolicy(ctx context.Context, id int64) error {
	return dao.DeletePolicy(ctx, id)
}

// GetPolicy Get Policy
func (d *DefaultManager) GetPolicy(ctx context.Context, id int64) (*policy.Metadata, error) {
	p1, err := dao.GetPolicy(ctx, id)
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, fmt.Errorf("no such Retention policy with id %v", id)
		}
		return nil, err
	}
	p := &policy.Metadata{}
	if err = json.Unmarshal([]byte(p1.Data), p); err != nil {
		return nil, err
	}
	p.ID = id
	if p.Trigger.Kind == policy.TriggerKindSchedule {
		cron, ok := p.Trigger.Settings[policy.TriggerSettingsCron]
		if ok {
			if cronStr, isStr := cron.(string); isStr && len(cronStr) > 0 {
				p.Trigger.Settings[policy.TriggerSettingNextScheduledTime] = strfmt.DateTime(utils.NextSchedule(cronStr, time.Now()))
			}
		}
	}
	return p, nil
}

View on GitHub (pinned to 7b2fd08cc5)