Repository navigation
EN Team Write Refused 423
Français · Type: troubleshooting · Audience: author · Context: hosted Studio · Status: ready · Applies from: 4.2.1
The Studio Server (hosted team Studio) · contract: experimental · verified by CI (support matrix of 4.4.0, 2026-10-23): Postgres, S3 and Keycloak in CI; Chromium and Firefox (job studio-hosted); WebKit on macOS, by hand only · automated checks: jobs
studio-hosted,studio-install-smoke; CI planstudioHosted; 3 test files · people's passes:studio-hostednot run (#149),studio-collabnot run (#150),studio-previewnot run (#166),studio-assets-hostednot run (#167),studio-mcp-remotenot run (#196),studio-oidc-genericnot run (#197) · known limits:hosted-only
On a team Studio, your save was refused with a 423: another member is editing the same part of the game. Your change is not lost, and nothing was written. This page says how to tell why, and how to get your change in.
- In the Studio: a dialog "The room kitchen is held by Léa" (or "The span story is held by…", or "The whole game is held by…"), with "Your change was not applied. Nothing is lost: your draft is kept here, to save when the span is free."
- Through the API, the CLI or the MCP: HTTP 423 with
{"error": "room:kitchen is being edited by Léa", "span", "holder", "holderName", "until"}, or"<name> has the whole game for now", or"your lease on <span> ended or was taken again: take it again".
Every file of the game belongs to one span: a room (its code and its layout), a language, the story, the items, the cast, the rules, the voices, the assets, the notes, the map's groupings, the rest. Saving a file takes its span for you for 120 seconds, a lease. Your Studio renews your leases every 30 seconds for as long as it stays open. Then:
- Another member holds that span's lease: they saved in that room, or took it ahead, and their Studio is still open (or was closed less than two minutes ago). The most common case.
-
A member holds the exclusive lease (
*): the whole game is theirs while a job that touches everything runs. Prepare and the cutting of the Assets tab take it for the dev who starts them; an engine upgrade and a Git import take it for the owner who starts them; each gives it back when its job ends. An owner can also take it by hand. Nobody else writes meanwhile. -
A script's lease ended or was taken over. A client that sends the fences it was given (
x-studio-fences) is refused when its lease ran out or an owner took the span over since. Only API clients that choose to send them get this; the Studio and the MCP do not. Your own lease never refuses you, from any of your tabs.
Limit ·
hosted-onlySpans and leases exist on a hosted Studio (the Studio Server) only. The local Studio (npm run studio) has one person and no 423.
- The dialog names the holder. The Studio's Spans panel lists who holds what, and until when; it follows the server's live events.
- As a member,
GET /api/leasesgives every lease:span,holderNameanduntil(a time on the server's clock, in milliseconds). - A span
*in the list is an exclusive lease: itsholderNameis the member whose job (or whose hand) holds it. - The message "your lease on … ended or was taken again" is cause 3, and only a script sending
x-studio-fencessees it.
- Wait. Click "Tell me when it is free": the Studio tells you as soon as the lease is given back or runs out. A lease runs out 120 seconds after the holder's Studio stops renewing it (their tab closed, their machine asleep); while their Studio stays open, they keep it, so ask them (next step). Then click "Try again": your draft is sent as it is.
- Ask. Tell the holder you need that room. When they release the span in their Spans panel, it is free at once.
-
Take it over (owner only). An owner can click "Take over and save (owner)": the span becomes theirs and the
change is saved. The previous holder's next write in that span is refused in turn. The takeover is written in the
audit log (
lease-takeover, with the previous holder). Through the API:POST /api/leases/takeoverwith{"span": "room:kitchen"}.
-
The exclusive lease. When someone holds the whole game (
*) for a job (Prepare, a cutting, an engine upgrade, a Git import), wait for the job to end: the lease is given back with it. An owner who took it by hand gives it back withPOST /api/exclusive/release, or it runs out. Taking it by hand (POST /api/exclusive) and releasing it by hand are an owner's; it is granted only when nobody else holds a span.
For cause 3, the script takes the span again (POST /api/leases with {"spans": ["room:kitchen"]}), keeps the new
fences it gets, then sends its write again.
The save goes through: the Studio shows the new revision, and the Spans panel shows the span as yours. Through the API, the write answers 200 with the revision it made.
- 409, "The file changed since you read it": nobody holds the span, but someone saved the same file after you opened it. That is not a lock; see Write refused on the hosted Studio: stale base revision (409).
-
503 with
Retry-After: the instance does not serve writes yet, during a redeploy. Wait a few seconds; the Studio retries. - A Reality Bridge never answers 423.
Generated publication · publication générée — current documentation · documentation courante: quest'n'click 4.4.0 r1, documentation revision · révision de la documentation 8dc717c69acb62c4742b69c54a7e7dfb620f75d8.
Earlier versions and permalinks · versions précédentes et liens permanents: https://wanoo.github.io/quest-n-click/docs/
An edit made in this wiki is overwritten at the next publication · une modification faite dans ce wiki est écrasée à la publication suivante.
Edit the source · Modifier la source · Report an error · Signaler une erreur
Index (6)
Start (6)
Play (9)
Install (17)
- Requirements
- Install from the release archive
- Install from npm, once published
- Install from the repository to work on the engine
- doctor: checking your machine
- Image toolchain
- Audio toolchain: ffmpeg, fluidsynth, Furnace, uv
- Upgrade
- Upgrade notes: 4.4
- Upgrade notes: 4.3
- Upgrade notes: 4.2
- Upgrade notes: 4.1
- Upgrade notes: v3
- Upgrade notes: v2 to v3
- Coming from web-scumm
- Package reference
- Install troubleshooting
Create a game (55)
- Your first game
- Layout of a created project and of the engine repository
- The working loop
- Content principles and the identity contract
- Rooms
- Geometry: placement, walk zones, masks, layers, camera
- Something is visible but unreachable
- Reactions
- Game commands
- Conditions
- Flags, variables and events: which to use
- Custom code
- Characters
- Items and inventory
- World map
- Dialogues
- Scripts and events
- Moving characters: patrols and walks
- Exits
- Chapters and objectives
- State and saves: persistent or temporary, renaming an id, migrations
- Staging: wide rooms and animations
- The stage: lights, particles, floors
- Skin and fonts
- Title and credits
- Heroes: several characters and hero choice
- Built-in minigames
- A custom minigame
- Translations
- Music in stems
- Sound effects
- Voices: per language and per hero
- Images: prompts, cutting sheets, transparency, scale
- Asset provenance
- The storyboard, source of truth
- Puzzle design
- Classic mechanics
- Review pages
- DSL reference
- Checking your game
- What the solver proves
- Solver options
- Playtests
- Remix
- Speedrun for authors
- The sealed ending
- Production template
- Example games
- Working with an AI
- Build and release a game
- Publish on GitHub Pages
- The static game on Clever Cloud
- Other static hosts
- Sub-path, cache and service worker, incomplete deploys, going back
- Testing on a phone over the LAN
Local Studio (24)
- The local Studio: overview and launch
- Edit a room
- Placement and stage
- Preview, apply, undo
- Storyboard
- Assets and cutting
- Check: validator, solver, critical path, heat, health, coverage
- Before and after captures
- Semantic diff
- Play and replay a session
- Rule explainer
- Language and objectives
- Voices and the heroes × languages matrix
- Map
- Notes
- Remix in the Studio
- Music
- The Assistant: bring your own key
- Demo mode and studio-apply
- Local and LAN security
- Studio API
- Local MCP: setting up each client
- MCP tools
- Studio troubleshooting
Team Studio (21)
- What runs where
- Concepts: revision, transaction, span, lease, preview, build
- Starting as an invited dev
- Working together day to day
- Roles and actions: the full matrix
- Invitations
- Managing members
- Write refused on the hosted Studio: stale base revision (409)
- Write refused on the hosted Studio: span locked (423)
- Recovering after a lost lease, a disconnection or a stale preview
- Comments
- Map and semantic diff
- Publishing builds
- Remote MCP
- The game in Git
- Upgrading the engine of a hosted game
- Hosted assets
- The server's command line
- Health and metrics routes
- Trying it locally with compose.yml
- Known limits
Clever Cloud (23)
- Clever Cloud: overview, cost and prerequisites
- Apps and add-ons
- Domains and TLS
- Keycloak
- Generic OIDC and GitLab
- Configuration
- First deployment
- Backups
- RPO and RTO
- Restore the Studio on a fresh installation
- Redeploys
- Upgrading the server and checking state after a migration
- Limits of going back
- Monitoring
- Security
- Rotating keys
- Recovering admin access
- Changing domain or OIDC provider
- Worker, PostgreSQL or Cellar down
- Exporting the game and leaving the installation
- Retention
- Clever Cloud troubleshooting
- Costs and teardown
Reality Bridge and connectors (16)
- The Reality Bridge: what it is
- Quick start
- Guarantees
- Install and run the Bridge
- Backup and restore
- Several tenants
- Signals and the manifest
- The Bridge's command line
- Connectors overview
- Email connector
- Telnet connector
- SSH connector
- Open Badges connector
- The connector SDK
- Security: Biscuit and signatures
- Bridge and connector troubleshooting
Contribute (25)
- Welcome
- Developer setup
- The dev loop
- Before a pull request
- Conventions
- Writing documentation
- Architecture
- Code tour
- Import boundaries
- Which tests run when
- Mutation testing
- The coverage ratchet
- The quality baseline
- CI explained
- Field passes
- Benchmarks
- Releasing
- npm packages
- Decisions and ADRs
- Governance
- Bot pull requests
- Contributing with AI agents
- Security policy
- Code of conduct
- Licences and credits