semaphoreui/semaphore · error

inventory does not exist in inventories[].name

Error message

inventory does not exist in inventories[].name

What it means

Thrown by BackupTemplate.Verify when the template has an optional Inventory set but its name is absent from backup.Inventories. Because the reference is optional (nil skipped), the error only fires for templates that actually declare an inventory that cannot be resolved.

Solutions

  1. Add the inventory with that name to backup.Inventories.
  2. Point the template's inventory field at an existing inventories[].name.
  3. Clear the inventory reference (set to null) if the template no longer needs one.

Example fix

// before
"templates": [{"name": "build", "inventory": "prod-inv"}], "inventories": []
// after
"templates": [{"name": "build", "inventory": "prod-inv"}], "inventories": [{"name": "prod-inv"}]
Defensive patterns

Strategy: validation

Validate before calling

if t.Inventory != nil && !invNameExists(*t.Inventory, backup.Inventories) {
  return fmt.Errorf("template %q references missing inventory %q", t.Name, *t.Inventory)
}

Type guard

func invNameExists(name string, invs []BackupInventory) bool {
  for _, i := range invs {
    if i.Name == name { return true }
  }
  return false
}

Try / catch

if err := tmpl.Verify(backup); err != nil {
  if strings.Contains(err.Error(), "inventory does not exist") {
    // add the inventory or clear the reference
  }
}

Prevention

When it happens

Trigger: Verify with e.Inventory != nil and getEntryByName[BackupInventory](e.Inventory, backup.Inventories) == nil — inventory renamed after the backup, or inventories excluded from export while templates were included.

Common situations: Selective export omitting inventories; environment-specific inventories that exist in the source but not the target project; case mismatches after manual JSON editing.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/6ae193154dba536f. Report an issue: GitHub.

Appendix: source

Thrown at services/project/restore.go:253

	newRepo, err := b.store.CreateRepository(repo)
	if err != nil {
		return err
	}
	b.repositories = append(b.repositories, newRepo)
	return nil
}

func (e BackupTemplate) Verify(backup *BackupFormat) error {
	if err := verifyDuplicate[BackupTemplate](e.Name, backup.Templates); err != nil {
		return err
	}

	if getEntryByName[BackupRepository](&e.Repository, backup.Repositories) == nil {
		return fmt.Errorf("repository does not exist in repositories[].name")
	}

	if e.Inventory != nil && getEntryByName[BackupInventory](e.Inventory, backup.Inventories) == nil {
		return fmt.Errorf("inventory does not exist in inventories[].name")
	}

	if e.VaultKey != nil && getEntryByName[BackupAccessKey](e.VaultKey, backup.Keys) == nil {
		return fmt.Errorf("vault_key does not exist in keys[].name")
	}

	if e.Vaults != nil {
		for _, vault := range e.Vaults {
			if vault.VaultKey != nil {
				if getEntryByName[BackupAccessKey](vault.VaultKey, backup.Keys) == nil {
					return fmt.Errorf("vaults[].vaultKey does not exist in keys[].name")
				}
			}
		}
	}

	if e.View != nil && getEntryByName[BackupView](e.View, backup.Views) == nil {
		return fmt.Errorf("view does not exist in views[].name")

View on GitHub (pinned to 1774ccb71a)