goharbor/harbor · error · Exception
cache expire hours should be positive number
Error message
cache expire hours should be positive number
What it means
SBOM report manager GetBy requires a non-zero artifact ID as the mandatory lookup key; artifactID == 0 returns 'no artifact id to get sbom report data' before any query keywords are built. The other filter parameters (registration uuid, mime, media type) are optional narrowing filters.
Source
Thrown at make/photon/prepare/models.py:242
interval = self.interval[:-1]
if not interval.isnumeric() or int(interval) < 2:
raise Exception('purge upload interval should set with with nh, n is the number of hour and n should not beless than 2')
return
class Cache:
def __init__(self, config: dict):
if not config:
self.enabled = False
self.enabled = config.get('enabled')
self.expire_hours = config.get('expire_hours')
def validate(self):
if not self.enabled:
return
if not self.expire_hours or self.expire_hours <= 0:
raise Exception('cache expire hours should be positive number')
return
class Core:
def __init__(self, config: dict):
self.quota_update_provider = config.get('quota_update_provider') or 'db'
def validate(self):
if not self.quota_update_provider:
return
if self.quota_update_provider not in ['db', 'redis']:
raise Exception('invalid quota update provider: {}'.format(self.quota_update_provider))View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Parse and validate the artifact ID at the API boundary, returning 400 for missing or invalid values
- Return 404 from the handler when the ID is absent rather than calling GetBy
- Propagate strconv errors instead of continuing with the zero value
Example fix
// before
reports, err := mgr.GetBy(ctx, artID, reg, mime, media) // artID may be 0
// after
if artID == 0 {
return nil, errors.New("artifact id is required to fetch sbom reports")
}
reports, err := mgr.GetBy(ctx, artID, reg, mime, media) Defensive patterns
Strategy: validation
Validate before calling
if artifactID == 0 {
return nil, errors.New("artifact id required to fetch sbom reports")
}
return mgr.GetBy(ctx, artifactID, regUUID, mime, mediaType) Try / catch
if _, err := mgr.GetBy(ctx, artifactID, reg, mime, media); err != nil {
if strings.Contains(err.Error(), "no artifact id") {
return nil, errors.New("artifact id not parsed from request path")
}
return nil, err
} Prevention
- Parse path parameters with error propagation
- Return 400 at the handler when the artifact id is missing
- Add contract tests for handlers with empty id parameters
When it happens
Trigger: GetBy(ctx, 0, regUUID, mime, media) — the artifact ID from the API path or event was never parsed, e.g. a strconv.Atoi error was ignored and the value defaulted to 0.
Common situations: URL-parameter parsing failures swallowed in handlers; events forwarded without artifact IDs; tests calling GetBy with zero values.
Related errors
- purge upload interval should set with with nh, n is the numb
- purge upload interval should set with with nh, n is the numb
- invalid quota update provider: {}
- 127.0.0.1 can not be the hostname
- File {} not exist
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/07622090c2d5ec69.
Report an issue: GitHub.