semaphoreui/semaphore · error
Internal Server Error
Error message
Internal Server Error
What it means
GetSystemInfo (api/system_info.go:75) returns 500 'Internal Server Error' when helpers.Store(r).GetGlobalRoles() fails — the database query for global roles errored. Details (user_id, error) go to the log under context 'system_info'; the client only sees the generic 500.
Solutions
- Check the server log for 'Failed to get roles' with the underlying DB error.
- Verify database connectivity and credentials; test with a direct query of the roles table.
- Run pending database migrations (semaphore migrate / setup) to ensure role tables exist.
- Restart the service once the DB is healthy and retry the endpoint.
Example fix
# before: stale schema $ semaphore server # GetGlobalRoles fails: relation "roles" does not exist // after: apply migrations first $ semaphore migrate $ semaphore server
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: server health before calling system info
const health = await fetch('/api/ping');
if (!health.ok) throw new Error("Backend/database unhealthy; skip system-info call"); Try / catch
try {
const info = await getSystemInfo();
} catch (e) {
if (e.status === 500) {
await delay(backoff++ * 1000);
return getSystemInfoWithRetry(); // transient DB issues often resolve
}
} Prevention
- Monitor database connectivity and alert before app-level 500s appear
- Run schema migrations as part of every deployment
- Use a store/DB user with SELECT on roles tables
- Wrap system-info polling with bounded retry + backoff
When it happens
Trigger: GET the system-info endpoint when the backing store's GetGlobalRoles query fails: DB connection dropped, roles tables missing/not migrated, or store-level error.
Common situations: Database down or network partition between Semaphore and Postgres/MySQL; schema migrations not applied so the global-roles table is absent; read-only replica or permission issues for the DB user; transient connection pool exhaustion.
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.
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- Failed to link external account.
- OIDC sign-in failed: could not find or create the user…
- OIDC sign-in failed: invalid redirect URL.
- Error generating key
- no admins found in database; create a admin first
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/e21a24dffefa685a.
Report an issue: GitHub.
Appendix: source
Thrown at api/system_info.go:75
}
if util.Config.Mfa.Email.Enabled {
authMethods.Email = &LoginEmailAuthMethod{}
}
timezone := util.Config.Schedule.Timezone
if timezone == "" {
timezone = "UTC"
}
roles, err := helpers.Store(r).GetGlobalRoles()
if err != nil {
log.WithFields(log.Fields{
"context": "system_info",
"user_id": user.ID,
}).WithError(err).Error("Failed to get roles")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
var plan string
token, err := c.subscriptionService.GetToken()
switch {
case errors.Is(err, db.ErrNotFound):
err = nil
plan = ""
case err != nil:
log.WithFields(log.Fields{
"context": "system_info",
"user_id": user.ID,
}).WithError(err).Error("Failed to get subscription plan")
err = nil
plan = ""View on GitHub (pinned to 1774ccb71a)