DineGlobeDocs

Troubleshooting by scenario

Start from the symptom — a disappeared booking, a stuck table, a missing email, a refused scan — and find the answer.

GuestHostDoorManagerOwnerPlatform operator

This page starts from what you are seeing, not from an error code. Each section names the likely causes and the exact fix, with the underlying codes in inline code so you can cross-read the full table in Error codes & fixes. Guests will usually see plain sentences instead of codes; staff panels may show both.

“My booking disappeared” — or it now shows as expired

The booking was not deleted. Every final state keeps the record, its reason and its decision time, visible on the guest portal (/b) or the staff board.

Likely causes

  • It was a request-mode booking and the venue did not decide within the deadline — the earlier of 24 hours after the request and the service start. The sweep sets the status to EXPIRED with reason REVIEW_DEADLINE or SERVICE_START.
  • It was a deposit booking and the checkout was not completed within the 10-minute hold. The hold expires (PAYMENT_HOLD_EXPIRED) and the tables are released.
  • A waitlist offer was not accepted within its 5-minute window (see the waitlist section below).
  • The guest cancelled it, or the venue declined the request with a reason.

The fix

  1. Open the booking again (guest portal or the staff board) and read the status and reason — that tells you which of the above happened.
  2. Book again from a fresh availability read: Making a booking. Expired and declined records cannot be edited — a new booking is the path (RESERVATION_INVALID_TRANSITION if you try otherwise).
  3. If request-mode deadlines keep expiring, ask the venue to watch its request queue: Request-approval bookings.

“I clicked Book twice — was I booked (or charged) twice?”

No. The booking form mints one request key when it loads. A double click, a retry, or a resubmit of the same form replays the same key, and the server answers with the SAME single booking — never a second one. Request keys live 24 hours.

Likely causes of anything unexpected

  • You changed details and resubmitted with the same key: IDEMPOTENCY_MISMATCH (409). No second booking is created; start the changed booking with a fresh form.
  • Two different searches or two different forms are honestly two attempts — each can book.

The fix

  1. Reload the confirmation. You will find exactly one booking with one DG-XXXXXXXX confirmation code.
  2. About charges: during the pilot no payment is taken at all — paid bookings are refused honestly (PAID_BOOKING_UNAVAILABLE). When payments are enabled later, a checkout timeout (PAYMENT_CHECKOUT_TIMEOUT) is retried under the same idempotency key, which continues the SAME checkout and can never create a second charge. See Payments (pilot posture).

“The table I want says unavailable” when I submit

Likely causes

  • SLOT_UNAVAILABLE (409): another party took the tables between your availability read and the booking commit. The answer carries up to 4 nearest open alternatives.
  • AVAILABILITY_STALE (409): the venue changed its schedule or offerings after your availability snapshot.
  • POLICY_STALE (409): the booking terms changed after you accepted them.
  • The slot was greyed out with “too soon — call us”: it sits inside the venue’s booking notice window. Online booking can never skip the notice rule; only staff at the venue can book it.

The fix

  1. For SLOT_UNAVAILABLE, pick one of the attached alternatives and rebook — the same form stays filled in.
  2. For AVAILABILITY_STALE, reload availability for the same day and book from the fresh picture.
  3. For POLICY_STALE, review and accept the current terms, then rebook.
  4. For notice-window slots, choose another day or contact the venue directly. If one slot fills every day, ask the manager to review the schedule and pacing: Offerings & schedules.

All link failures answer the same generic denial (TOKEN_INVALID, 401) — the system never tells you which one it was. The differences matter only for choosing the fix. The emailed link’s token lives 24 hours, works exactly once, and is replaced (together with every session it created) whenever a newer link is issued. After the one-time exchange you get a 60-minute session for that one booking.

Likely causes

  • The 24-hour token expired.
  • The link was already used once — the exchange is single-use.
  • A newer link was issued (by you or by staff) — reissuing rotates, and every older link and session dies immediately.
  • The 60-minute session lapsed while you were reading.
  • The link was for the waitlist queue, not the booking — each door rejects the other’s secret with the same generic denial.

The fix

  1. On the portal landing page (/b), use “Lost your link?”: enter the email you booked with and your confirmation code (DG-XXXXXXXX). If they match a booking, a fresh link is sent to that address. The answer is always the same regardless, and the code alone never grants access.
  2. Recovery is rate-limited to 5 requests per hour per email (RATE_LIMITED if you exceed it) — wait rather than retry rapidly.
  3. Staff can also issue a fresh management link directly; ask the venue. More detail: Guest self-service links.

“A table is stuck as occupied”

By design, no timer ever frees a table. A party that overruns its planned end keeps occupying the table until a staff member explicitly records the departure. Nothing about the booking lifecycle, the schedule or the clock releases occupancy on its own.

Likely causes

  • The earlier party was seated and never checked out — the visit is still SEATED.
  • Seating a new party there answers OCCUPANCY_CONFLICT (409), which names the party that holds the table.

The fix

  1. Open the holding party’s reservation from the day board and use “Complete & clear” (Record departure, release tables). The occupancy moves to CLEANING and the table becomes seatable.
  2. Then seat the waiting party, or move them to a free table.
  3. Follow the floor in real time on the service board: The service board. Visit states are explained in Arrivals, seating & visits.

“The scan says wrong venue” or “outside the window”

Door scans answer with specific codes (the guest sees nothing about the other booking either way):

Message Code Meaning and fix
Wrong venue CHECKIN_PASS_WRONG_VENUE (422) The pass was issued by a different venue. Direct the guest to the issuing venue; no details are revealed here.
Outside the window CHECKIN_PASS_WINDOW (422) Passes scan from 60 minutes before the booked start until the booked end. Scan again inside that window; if the booking was rescheduled beyond the pass’s stamped expiry, issue a fresh pass.
Invalid pass TOKEN_INVALID (401) Unknown, revoked, rotated or expired — all identical on purpose. Issue a new pass for the reservation.

Also check

  • No camera is involved: camera capture is not implemented in V1. Scanning the pass means typing or pasting the pass token, and the manual arrival form is the implemented fallback.
  • The device is offline? Scans are online-only: a refused scan records nothing and queues nothing (OFFLINE, 503). Take the arrival by hand — type the guest’s confirmation code into the manual arrival form instead of the scanner.
  • A re-scan of an already-arrived party answers “Already checked in — nothing recorded again” (DUPLICATE) and replays the party’s current status. Nothing is double-counted.

Pass mechanics live in QR check-in passes; arrivals and corrections in Arrivals, seating & visits.

“My waitlist offer vanished”

Offers live for exactly 5 minutes — the offer is a real held table on the slot grid, and the hold must return quickly for other guests.

Likely causes

  • The 5 minutes passed before acceptance: the sweep marks the offer EXPIRED, releases the held table, and returns the entry to WAITING keeping its original place (the join time is untouched). The guest sees WAITLIST_OFFER_EXPIRED (422): “The offer expired and its table was released.”
  • The host withdrew the offer, or the offer was already accepted: WAITLIST_OFFER_CONFLICT (409).

The fix

  1. Nothing was lost — check the queue board: the entry is back in line at its original position.
  2. Wait for the next offer and accept within 5 minutes through the queue link. Acceptance converts the same held table into the confirmed booking — no second booking is created.
  3. Queue rules and the host workflow: Waitlist.

“No email or SMS arrived”

Pilot fact: during the unpaid pilot no email or SMS provider is configured, so nothing actually sends. Message dispatch fails visibly — the delivery evidence records a FAILED outcome and the outbox job dead-letters — and the system never fakes a send. This is the designed honest posture, not a fault.

What each case means

  • The booking still confirmed in the app with its DG-XXXXXXXX code; only the email is missing. The delivery evidence shows FAILED (recipients are masked in staff views). Once a provider is configured, a manager can retry the failed job; retrying anything that is not FAILED answers CONFLICT.
  • A walk-in with no email address records NO_RECIPIENT — an honest absence; no address is ever invented.
  • The evidence may show SUPPRESSED with a reason instead: the message was superseded by an edit (STALE_EVENT), landed after service (REMINDER_PAST_SERVICE), the booking was already reconfirmed (ALREADY_RECONFIRMED), or the venue’s quiet hours apply (QUIET_HOURS).
  • SMS is gated off entirely in V1; its gate ladder (SMS_VENUE_DISABLED, SMS_COUNTRY_NOT_APPROVED, SMS_ROUTE_NOT_APPROVED, SMS_QUOTA_NOT_APPROVED, SMS_COST_CAP_EXHAUSTED) records each refusal.
  • Demo-venue bookings never send anything — the demo is seeded directly, with zero background message jobs.

The fix

  1. Give the guest their confirmation code — it identifies the booking at the venue without any email.
  2. Staff: check the delivery evidence for the reservation; read the outcome and reason before assuming anything.
  3. Managers: retry a FAILED job only once a provider exists. Messaging behavior in depth: Messages, confirmations & reminders; the pilot’s honest limits: What works today & known limits.

“I cannot enable a deposit offering”

Payments run behind explicit capability gates that are closed during the pilot, and the product refuses rather than pretends.

Likely causes — each names itself

  • Activating the offering: PAYMENT_NOT_READY (422) with a paymentMode field error naming the exact block — NO_ACCOUNT (no connected account), CHARGES_DISABLED (charges off on the account), CURRENCY_MISMATCH (settlement currency differs), or COUNTRY_NOT_APPROVED (no approved capability for the country).
  • A guest trying to book the deposit offering: PAID_BOOKING_UNAVAILABLE (422) — deposits cannot complete online in this posture.
  • A DEPOSIT policy cannot even pass publication readiness without a ready account, so the venue stays unpublished for that offering.
  • An operator enabling the payment capability against a sandbox or missing provider in production: CAPABILITY_NOT_ACTIVATABLE (422).

The fix

  1. The owner (or org admin) connects the venue’s payment account and refreshes capability truth, then resolves the named block from PAYMENT_NOT_READY: Payments (pilot posture).
  2. Until the gates pass with evidence, keep offerings free or request-mode: Booking policies & cancellation.
  3. Scope: single-market pilot evidence only — one approved country and its listed capabilities; unlisted countries and capabilities stay disabled until each passes a signed readiness review. The verbatim statement is published on the public capabilities page.

“New bookings are refused, but existing ones still work”

Intake suspension blocks only NEW bookings. Everything already booked keeps working: management, cancellation, refunds and exports are unaffected.

Likely causes

  • SUBSCRIPTION_INTAKE_SUSPENDED (402): the venue’s subscription trial ended, a past-due grace period expired, or the period ended without renewal.
  • PLATFORM_INTAKE_SUSPENDED (422): the platform operator suspended new intake for the venue.

Both refuse on every booking path — guest online booking, staff walk-ins, and CSV import.

The fix

  1. For billing suspension: the owner settles the subscription (pay or renew). New bookings resume automatically once entitlement is restored: Subscription billing.
  2. For platform suspension: contact the platform operator — lifting it is an operator decision: Platform operator console.
  3. Guests with existing bookings need no action; their bookings, links and cancellation keep working.

“Someone can’t see a venue or bookings they should”

Two different failures hide behind this symptom, and the distinction is deliberate:

  • No membership for that venue: reads answer NOT_FOUND (404) — a venue you are not attached to looks exactly like one that does not exist. There is no existence oracle.
  • Role too low: the venue is visible but the action answers PERMISSION_DENIED (403) — for example a HOST trying to approve requests, or a DOOR role trying to manage the queue.

Also remember the scope shapes: only OWNER and ORG_ADMIN sit org-wide; MANAGER, HOST, DOOR, FINANCE and READ_ONLY are always venue-scoped. Someone attached to venue A sees nothing from venue B, even in the same organization, unless they hold a row there too.

The fix

  1. Confirm which venue and which action. If nothing at that venue is visible: an owner or org admin adds the membership (invite the person, or assign the venue-scoped role).
  2. If the venue is visible but an action is refused: grant the role that carries the permission. Note that a MANAGER may only grant HOST, DOOR or READ_ONLY — raising someone to MANAGER or FINANCE needs an owner or org admin.
  3. Role changes take effect on the person’s next request; have them reload and retry, signing in at /app/login and opening the venue from “Your venues”.
  4. The full matrix: Roles & what they can do and Organizations, teams & invitations.

“Import rejected my file”

The importer refuses the whole file up front for structure problems (before any row is stored) and refuses individual rows for content problems. Run the dry run first — nothing is booked until you explicitly commit.

Rejection Code Fix
File is not valid UTF-8 IMPORT_ENCODING (400) Re-export the file as UTF-8; nothing was stored.
File over 10 MB IMPORT_TOO_LARGE (400) Split the file.
Over 10,000 data rows IMPORT_TOO_MANY_ROWS (400) Split into batches of at most 10,000 rows.
No header row IMPORT_CSV_EMPTY (400) Add the header row and upload again.
Broken CSV quoting IMPORT_CSV_MALFORMED (400) Fix unterminated quotes or quotes inside unquoted cells.
A mapped column is missing IMPORT_HEADER_MISSING (400) Correct the mapping — each missing column is named in the field errors.
A row’s time is not on an open slot IMPORT_OFF_GRID (422) Align the row to the venue’s bookable slots — check schedules and date exceptions, and set the file’s timezone field correctly (the IANA zone the file’s times are written in).
The row’s policy is a deposit policy IMPORT_PAID_POLICY (422) Imported bookings are never charged, so paid rows are refused. Import non-paid offerings only.

The fix

  1. Fix the named problem and stage the dry run again; rejected and failed rows always carry their error text.
  2. Commit when the dry run is clean. Commits are crash-safe and a repeated external id can never become a second booking.
  3. Step by step: CSV import.

“Export download says not ready”

Message Code Fix
Still rendering EXPORT_NOT_READY (409, retryable) The job is QUEUED — wait a moment and retry the download.
Render failed EXPORT_FAILED (410) Start a new export job; if it repeats, report the job id to the operator.
Too many rows EXPORT_TOO_LARGE (422) The service sheet is bounded at 2,000 rows — narrow the date range or filters, or use the data-export feature.
Gone NOT_FOUND (404) READY artifacts stay downloadable for 24 hours; after that generate a fresh export.

The fix

  1. Retry the download shortly after queueing — renders are done by the background worker, not the click.
  2. For repeated EXPORT_FAILED, note the render error text and the job id before starting a new job.
  3. Export surfaces and windows: Service sheet & CSV exports.

“An MFA prompt appeared in the middle of a task”

Two-step verification prompts appear exactly when the action needs a verified code and your session does not currently have it.

Likely causes

  • You signed in with an MFA-enrolled account: sign-in itself always asks for a 6-digit code (or a recovery code).
  • A money action — requesting or approving a refund — requires MFA verified within the last 30 minutes. If your verification is older, the action answers MFA_REQUIRED (401).
  • A platform or operations surface requires an MFA-verified session.

The fix

  1. Complete the code prompt promptly and continue the task — the assurance is time-boxed, so finish the sensitive step within the window.
  2. MFA_CODE_INVALID (401): the code was wrong, reused or outside its time step. Each 6-digit code works once — wait for the next one in your authenticator rather than resubmitting the same code. Recovery codes also work exactly once each.
  3. If you are mid-refund and the window closed, re-verify and redo the step; the refund flow is fail-closed by design: Refunds. Managing your factor and recovery codes: Your account & security.

“I hit a rate limit”

RATE_LIMITED (429) is the generic quota code marked safe to retry — wait the window, then try again. The known windows:

Surface Window
Password sign-in 10 attempts per 15 minutes per account
One-time identity links (verify, reset, link) 5 issued per 15 minutes per account
Guest link recovery (email + code) 5 per hour per email address
Guest portal token exchange 60 per hour per source address
Demo role sign-ins 10 per hour per client IP — counted before provisioning, so failed attempts count too

The fix

  1. Wait out the window; the demo card says “Too many demo sign-ins from this network — try again later.”
  2. For the demo specifically, switching roles does not reset the counter — it is per network, per hour.
  3. If a staff sign-in is locked out by repeated wrong codes, pause, then sign in fresh with the authenticator ready: Your account & security. The demo itself is described in Try the live demo.

Where to look next