semaphoreui/semaphore · error
key not found
Error message
%s key %s not found
What it means
TypeKeyMapper.getNewKey looks up the replacement key for an entity being imported/exported in the map Keys[name][scope][oldKey]. When no mapping exists for the given type name, scope, and old key, it fails so the export/import can silently skip or mis-reference an entity.
Solutions
- Re-generate the export file from the same (or compatible) source instance/version as the target
- Ensure all entities of the given type are loaded and registered in the TypeKeyMapper (via mapKeys) before resolving dependent keys
- Check that the scope string matches exactly between where keys were mapped and where getNewKey is called
Example fix
// before
newKey, err := mapper.getNewKey("project", scope, oldKey) // panics into error when missing
// after
if _, ok := mapper.Keys["project"][scope][oldKey]; !ok {
log.Warnf("skipping unmapped project key %s", oldKey)
return nil
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, ok := mapper.Keys[name][scope][oldKey]; !ok {
// handle missing mapping before calling getNewKey
} Try / catch
newKey, err := mapper.getNewKey(name, scope, oldKey)
if err != nil {
if strings.HasSuffix(err.Error(), "not found") {
// skip entity or create a fresh mapping via mapKeys
return nil
}
return err
} Prevention
- Always call mapKeys for every loaded entity before resolving dependent keys
- Keep source and target Semaphore versions aligned
- Log unmapped keys during import for diagnosis
When it happens
Trigger: During export/import key remapping, getNewKey (called by getNewKeyInt/getNewKeyIntRef) is asked for a mapping of an old EntityKey that was never registered via mapKeys for that entity type and scope — e.g. the source export references an object the target store never loaded, or IDs shifted between versions.
Common situations: Importing an export file produced by a different Semaphore version or different instance where referenced entity IDs (project, template, inventory keys) do not exist in the destination; stale or partially-loaded export data.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/f2f998a4802fc032.
Report an issue: GitHub.
Appendix: source
Thrown at services/export/Exporter.go:154
errHandler.onError(err.Error())
return nil, nil
}
return nil, err
}
newKey, err := strconv.Atoi(key)
if err != nil {
return nil, err
}
return &newKey, nil
}
func (d *TypeKeyMapper) getNewKey(name string, scope string, oldKey EntityKey) (EntityKey, error) {
newKey, ok := d.Keys[name][scope][oldKey]
if !ok {
msg := fmt.Sprintf("%s key %s not found", name, oldKey)
return "", errors.New(msg)
}
return newKey, nil
}
func (d *TypeKeyMapper) mapKeys(name string, scope string, oldKey EntityKey, newKey EntityKey) error {
_, ok := d.Keys[name]
if !ok {
d.Keys[name] = make(map[string]map[EntityKey]EntityKey)
}
_, ok = d.Keys[name][scope]
if !ok {
d.Keys[name][scope] = make(map[EntityKey]EntityKey)
}
d.Keys[name][scope][oldKey] = newKey
return nilView on GitHub (pinned to 1774ccb71a)