semaphoreui/semaphore · error

err

Error message

err

What it means

In `vault check`, the panic fires when the read-only walk over all locally encrypted access keys (`eachLocalAccessKey` -> project/access-key store queries) returns an error. The command is meant to report key usage; a database failure during enumeration aborts the whole check. The panic message is generic — the wrapped DB error matters.

Solutions

  1. Verify database connectivity and grants for the configured user.
  2. Rerun after confirming the Semaphore schema is migrated to the CLI's version.
  3. Inspect the wrapped error in the stack trace for the failing table/query and fix at the DB level.
  4. Run `semaphore vault check` on a database snapshot locally to separate DB issues from key issues.
Defensive patterns

Strategy: try-catch

Validate before calling

if err := store.GetAllProjects(); err != nil {
    // abort check early with a clear message instead of walking keys
}

Try / catch

if err := eachLocalAccessKey(store, fn); err != nil {
    fmt.Fprintf(os.Stderr, "vault check aborted: %v\n", err)
    os.Exit(1)
}

Prevention

When it happens

Trigger: Running `semaphore vault check` while `store.GetAllProjects()` or any `store.GetAccessKeys(...)` page query fails: database down, permission denied, or schema mismatch.

Common situations: Database credentials/connection issues in config; CLI run against a database from a newer/older Semaphore version; read-only DB user missing SELECT grants on projects/access_key tables.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at cli/cmd/vault_check.go:51

		}

		counts := map[string]int{} // key id ("" = legacy/no prefix) -> row count
		var total, missing int

		err := eachLocalAccessKey(store, func(key db.AccessKey) error {
			if key.Secret == nil || *key.Secret == "" {
				return nil
			}
			total++
			id := util.SecretKeyID(*key.Secret) // "" for legacy un-prefixed values
			counts[id]++
			if id != "" && !util.Config.HasKeyID(id) {
				missing++
			}
			return nil
		})
		if err != nil {
			panic(err)
		}

		fmt.Printf("Access keys: %d total\n", total)

		// Report every key id seen in the database, plus keyset keys with no rows.
		ids := map[string]struct{}{}
		for id := range counts {
			ids[id] = struct{}{}
		}
		for _, id := range util.Config.KeyIDs() {
			ids[id] = struct{}{}
		}
		sorted := make([]string, 0, len(ids))
		for id := range ids {
			sorted = append(sorted, id)
		}
		sort.Strings(sorted)

View on GitHub (pinned to 1774ccb71a)