#Setup and databases

  • pnpm setup:check: reports exact missing native dependencies without modifying the
  • SQLite issues in local mode: confirm .local/studio.db exists and

prisma/sqlite/schema.prisma is current (pnpm db:schema). Delete and rerun pnpm db:migrate && pnpm db:seed only when intentionally resetting local data.

  • MySQL unavailable in hosted mode: verify service status, strict mode, UTC, grants, and the

ignored local DATABASE_URL.

  • Keycloak import failure: validate realm JSON, secret files, hostname variables, and

database grants; do not switch production deployments to start-dev.

  • OIDC redirect error: compare the public TLS URL, exact redirect URI, and proxy headers.

#Sessions, users, and GEngine

  • Host not detected: GEngine and CandyCastle do not need another project registration.

The host is bundled at packages/userapp-host; run pnpm install and pnpm setup:check to repair the Studio workspace. The canonical profile should be named Local UserApp runtime and use port 3100. Use the external host override only for compatibility testing.

  • Process running but API unreachable: open Settings → Runtime and run **Diagnose

now**. Inspect the exact endpoint, HTTP status, content type, response preview, profile command, working directory, PID, and latest job error. The canonical profile must be Local UserApp runtime; a Vite page is not the UserApp API.

  • Unexpected token '<' or response starts with <!doctype>: the port belongs to an

HTML frontend, usually a project Vite process. Restart from Settings → Runtime. Studio scopes active executions and queued starts by profile ID, so current versions do not reuse another development profile as the host. The diagnostic response preview identifies the wrong process immediately.

  • Blank iframe, preload JSON error, or HTML beginning with <!doctype>: Studio must

start the selected project's Client development server before GEngine opens the AppContent. The client normally receives an internal port in the 5200–5499 range and must answer the worker's Vite health probe. In hosted mode the probe includes the advertised /api/live/runtime/<port>/ base path; probing /@vite/client at the server root can return a misleading 404 even while Vite is healthy. Review that project's runtime execution and terminal output, then retry synchronization. Studio maps the exact GEngine asset path (for example mods/cc/index.html) through KS_APP_CONTENT_DEV_OVERRIDES; guessed routes such as /candy are invalid. Remove clients created by older Studio versions after the host has restarted so GEngine can issue fresh sessions. In hosted mode, confirm Traefik routes /api/live/runtime/ to the worker gateway and that its forward-auth middleware reaches /api/runtime/gateway/authorize; do not publish the worker's runtime port ranges.

  • The selected game stays on the menu or another game: Studio now keeps a starting tile

pinned to its assigned AppContent path instead of displaying an unrelated live session. If synchronization reports that the assigned path did not open, inspect the GEngine mod's launch command and UI-access rule. For example, GEngine's Menu2.showGame() requires the selected mod to expose a hasUIAccess(user) function that returns true before it sends the AppContent document.

  • No development client was discovered: the registered game project needs an existing

dev or start script (or gengine.project.json developmentCommand) and a Vite dev.html or index.html containing a module entry. Studio reads this metadata but does not modify the external project.

  • Session start says the server build is required: open Projects and build the server

module, or use Reload server in an already active Session. Studio compares the project-owned gengineAdapter.serverModule.sourcePath and outputPath trees and does not rebuild backend code automatically.

  • Server status says reload required: generated output matches the source, but the running

GEngine sandbox loaded an older version. Use Preserve runtime to reload in place, or Restart session. If the overlay target or project set changed, restart is required once.

  • Client changes appear but server changes do not: this separation is intentional. Vite HMR

is automatic; GEngine server modules are built and reloaded only through Studio's explicit action. Confirm the project manifest declares sourcePath, outputPath, targetPath, and an argument-array buildCommand.

  • GEngine menu unavailable: confirm gengine.protectedPath points to the GEngine source

containing mods/Menu2.js and a built www/mods/menu2/game.html (or dist/www/mods/menu2/game.html). Game projects with a registered Vite client can still launch through their exact AppContent mapping when the optional built menu asset is absent.

  • Game unavailable in the app selector: the registered project must match a discovered

GEngine mod whose manager declares a UI path. Check the project name/slug or add project-owned adapter metadata containing the mod short identifier.

  • User remains connecting: the host may still be starting, GEngine may not be loaded,

the assigned project's development client may be unavailable, or /show <short> did not produce the expected AppContent path. Open the session Logs panel, inspect the app/host tabs, run Runtime diagnostics, then synchronize or restart the host.

  • Hosted sessions only show the GEngine menu: verify the web service has

STUDIO_RUNTIME_INTERNAL_HOST set to the worker service DNS name. Server-side probes use the worker network address, while browsers use the authenticated same-origin runtime gateway. Both paths must work before Studio can send /show <short> through GEngine.

  • Commands report no connected user: enable the persistent identity, assign it to a

saved session, start that session, and wait for provisioning. Commands use the same live identity and host state as Sessions.

  • Disabled user still appears: reload Users after the mutation. Disabling removes the

user from active session assignments; stopping a session always clears transient runtime IDs while retaining reusable profiles.

  • Private message rejected: choose a different connected target. Both users need real

runtime user IDs.

  • Iframe reload after navigation: use client-side Studio navigation. A full browser

refresh intentionally recreates the page; app switching, host restart, and user removal also change the relevant AppContent lifecycle.

#Contracts

  • No contracts discovered: select the correct app source and confirm source files are

present outside excluded generated directories. Discovery looks for event call and handler evidence; it does not invent events from app names.

  • Payload schema missing: source discovery proves event names and direction only. Add

contractMetadata.events or contractMetadata.contracts to the app's own gengine.project.json, with an inline schema and optional exampleFile. Studio never substitutes a game-specific built-in schema.

#Runtime, terminal, and native dependencies

  • node-pty build failure: install C++ build tools and Python, then reinstall with the pnpm

build allowlist.

  • Terminal denied: verify the project is writable, both terminal permissions are effective,

the shell is allowed, and worker time matches the web service.

  • A generic Vite app fails: inspect the detected development command, selected port, HMR

host, and readiness log. This guidance does not apply to the GEngine UserApp host, which uses its server API profile instead.