goharbor/harbor · error
empty rule template ID
Error message
empty rule template ID
What it means
Returned by rule index Valid(templateID, parameters) when the template ID string is empty. Rule templates (always, latestPulledN, daysSinceLastPull, etc.) are registered into an index; Valid rejects the empty key before lookup. It means a retention policy rule carries no template selector.
Source
Thrown at src/pkg/retention/policy/rule/index/index.go:185
// Register the rule evaluator with the corresponding rule template
func Register(meta *Metadata, factory rule.Factory, validator ...rule.Validator) {
if meta == nil || factory == nil || len(meta.TemplateID) == 0 {
// do nothing
return
}
index.Store(meta.TemplateID, &indexedItem{
Meta: meta,
Factory: factory,
Validators: validator,
})
}
// Valid ...
func Valid(templateID string, parameters rule.Parameters) error {
if len(templateID) == 0 {
return errors.New("empty rule template ID")
}
v, ok := index.Load(templateID)
if !ok {
return errors.Errorf("rule evaluator %s is not registered", templateID)
}
item := v.(*indexedItem)
// We can check more things if we want to do in the future
if len(item.Meta.Parameters) > 0 {
for _, p := range item.Meta.Parameters {
if p.Required {
exists := parameters != nil
if exists {
_, exists = parameters[p.Name]
}
View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Set a valid template ID on each rule, e.g. 'always', 'latestPushedK', 'daysSinceLastPull'
- Validate every rule has a non-empty template before POSTing the policy
- Check current template IDs supported by your Harbor version via the retention API metadata endpoint
Example fix
// before
if err := index.Valid("", params); err != nil { ... }
// after
if err := index.Valid("always", params); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
for _, r := range policy.Rules {
if len(r.Template) == 0 {
return fmt.Errorf("retention rule %v has no template", r.ID)
}
if err := ruleindex.Valid(r.Template, r.Params); err != nil {
return err
}
} Prevention
- Check rule.template is non-empty for every rule before policy submission
- Enumerate supported template IDs from the retention API before building rules
- Pin template IDs in code as constants to survive refactors
When it happens
Trigger: Creating/updating a retention policy whose rule omits or blanks the template field; policy JSON built programmatically with an unset rule.Template; payload corruption stripping the template key.
Common situations: Scripted policy creation missing required fields; Harbor API clients with schema drift after upgrade (template renamed/required); copy-paste from old policy exports.
Related errors
- empty action
- BAD_REQUEST
- File {} not exist
- Internal dir for tls {} not exist
- Port number in metrics is not valid
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/0405a1aa5fb722a3.
Report an issue: GitHub.