DisplaySync

Error codes

DisplaySync surfaces errors as human-readable messages in the dashboard, mobile app, and kiosk logs. The product doesn't yet ship a fully-structured error-code taxonomy — a planned v2 enhancement — so this page is organized by category and message text rather than alphabetic code lookup.

If you're searching for a specific message you're seeing in the UI, Ctrl-F / Cmd-F is your friend — every message below is reproduced verbatim.

Authentication & registration

MessageMeaningNext step
An account with this email already exists. Please sign in with your password and link Google in settings.Trying to sign in with Google for an email that has a password accountSign in with password, then link Google from Profile → Settings
Email already in useRegistration with an email that's already registeredSign in instead, or use a different email
Current password is incorrectPassword change with wrong current passwordReset via "Forgot password" if you don't remember
Email is already verifiedVerification link clicked twiceIgnore — the second click is harmless
RATE_LIMIT_EXCEEDED (429)Too many requests in a short windowWait 60 seconds and retry; persistent → contact support
CSRF_TOKEN_INVALID / CSRF_VALIDATION_FAILED (403)Stale dashboard session, or browser cookie issueHard refresh (Ctrl+Shift+R) the dashboard; if persistent, sign out and back in

Handshake-flow rows activate when enabled

The four device_* / sign_not_connected / request_in_progress rows below appear once your workspace has the link/claim handshake enabled (backend env flag LINK_HANDSHAKE_ENABLED). Pre-handshake workspaces won't surface these.

Sign claim & registration

MessageHTTPActivatesMeaningNext step
SHORTCODE_NOT_FOUND404The 6-char code doesn't match any pending signRe-scan the QR; if persistent, Sign won't claim
This device is already claimed409Trying to claim a signId already in another org/eventUnregister from the other event first, or follow the hardware-swap workflow
Sign is already linked and online400Linking a device to a sign record that already has a device attachedUnlink the existing device first
Sign has been unregistered — hardware was claimed by a new signn/a (kiosk message)Old kiosk learned its identity is now bound to a different physical deviceThe new claim wins — old kiosk shows QR for fresh re-claim
device_no_ack504Handshake activeKiosk did not ack the link/claim within timeout"Sign didn't respond. Check it's online and retry." See Sign won't claim.
device_load_failed400Handshake activeKiosk acked failure during load. Sub-reasons: url_unreachable, url_load_failed, sign_timeout.Verify the URL is reachable from the venue network; if URL is fine, retry — sign_timeout clears on retry.
sign_not_connected400Handshake activeNo active WebSocket session for the signPower-cycle the kiosk and retry.
request_in_progress409Handshake activeAnother claim/link request is in flight for this signWait a few seconds and retry.

Content & assignment

MessageMeaningNext step
Content not foundThe content ID referenced was deleted or never existedRe-paste a valid URL into the sign's Assigned URL field
Cannot update content for signs in an archived eventThe event was archived; content edits are lockedMove sign to a non-archived event, or unarchive
Command queued — sign will receive on reconnectSign offline; remote command was accepted but not yet deliveredWait for sign to reconnect, or reboot it
Content shows Unreachable in dashboardTwo consecutive HEAD checks failed against the assigned URLSee Content not loading

Event & organization

MessageMeaningNext step
Event not foundStale URL or deleted eventReturn to event list
Cannot add signs to an archived eventEvent is in archived stateUnarchive, or use a different event
Cannot link signs to an archived eventSame as above for link operationsSame
Cannot delete organization with existing events, signs, or contentOrg cleanup safety guardDelete or migrate child resources first
Cannot remove the last owner. Assign another owner first.Trying to remove the only org ownerPromote another member to owner, then retry
A pending invitation already exists for this emailInviting someone who already has an open inviteResend the original or revoke and re-invite

Permissions

When you don't have access to do something:

PatternHTTPMeaning
Forbidden / Permission denied403Your role doesn't permit this action
Organization access denied403You're not a member of this org
Event access denied403You're not on this event's team and the event isn't visible to your org role
Admin access required403The action requires the system admin role

For the full permission matrix, see Roles & permissions.

Connection & networking (kiosk side)

These appear in the kiosk's sign.log rather than the dashboard:

Log signatureMeaningNext step
[ERROR] WebSocket connection failed: ECONNREFUSEDBackend unreachableVerify firewall, see Network requirements
[ERROR] WebSocket error: ENETUNREACHNo route to backend (LAN/WAN dropped)Check venue uplink
[ERROR] Hostname not foundDNS failureCheck venue DNS, or set static
[ERROR] certificate has expiredKiosk clock is wrongNTP sync: w32tm /resync
[INFO] Attempting reconnection... (repeating)Constant reconnect cycleSee Sign shows offline → flapping

HTTP status codes used by the API

CodeWhen you see it
200 OKNormal success
201 CreatedResource created (sign claim, event create, etc.)
204 No ContentSuccessful delete, no body
400 Bad RequestValidation failed — message contains specifics
401 UnauthorizedNot signed in, or session expired
403 ForbiddenSigned in, but lack permission
404 Not FoundResource doesn't exist or you can't see it (404 vs 403 is sometimes deliberate to avoid leaking existence)
409 ConflictState conflict — already claimed, already linked, etc.
429 Too Many RequestsRate limited (auth routes are stricter). Wait 60s and retry; persistent 429s indicate a misconfigured client.
500 Internal Server ErrorUnexpected backend failure — contact support if persistent
502 Bad GatewayUpstream Fly proxy infrastructure error; not application code. If persistent, check Fly status, not backend logs.
503 Service UnavailableHealth endpoints emit 503 when DB is down or Redis is degraded. Also returned when assigning content to an offline sign — the assignment is recorded but the live broadcast fails; the assignment delivers when the sign reconnects.
504 Gateway TimeoutHandshake timeout from the acknowledged link/claim flow (device_no_ack) — see Sign claim & registration.

Sentry tags and context

Errors that bubble up to Sentry from a kiosk carry one tag and a sign context object for triage:

FieldTypeValueMeaning
sign.idtagUUIDThe kiosk that emitted the error
signId, organizationId, eventIdcontext (in sign)UUIDsOwning org and active event for the kiosk
appVersiontagsemverDesktop sign version
environmenttagproduction / stagingDeploy target

When opening a support request related to an error, including the kiosk's signId lets us correlate to Sentry events directly.

Future: structured error codes

A v2 enhancement will introduce structured error codes (E_SIGN_CLAIM_*, E_CONTENT_*, etc.) that decouple message text from machine-readable identifiers. Until then, the messages above are the source of truth and any error-handling code should match on text rather than codes.

See also