Skip to content

Latest commit

 

History

History
164 lines (142 loc) · 12.5 KB

FACILITATOR.md

File metadata and controls

164 lines (142 loc) · 12.5 KB

When something goes wrong (facilitator cheat sheet)

Symptom, then the fix. Run commands in the attendee's Ubuntu: ask their Claude session to run them, or open an Ubuntu terminal. On a Mac, ask their Claude session or use Terminal; their app folders are in the projects folder they chose (~/appdev by default; cat ~/.workshop/apps-dir shows it). Background is in INSTRUCTOR-NOTES.md, and what the family social network app does and does not include is in its section there.

Building

  • A compile is stuck, or compiling again (or saving the Plan) fails with 409 and compilation_active. A compile normally takes 30 to 45 seconds. The error names the Compilation, as current.compilation.id or in the 409's response.detail ("Compilation <id> is already active..." or "Cancel active Compilation <id>..."). Run these in the app folder (or in its .firstdraft/design if the app was already compiled once):
    1. Once CLI 0.8.2 is installed (firstdraft --version; npm install --global @firstdraft.com/cli@latest updates it): firstdraft compilation cancel <id>, then compile again.
    2. CLI 0.8.1 has no cancel. Wait 3 minutes, then firstdraft compilation status <id> --wait (it returns when the Compilation finishes, or after 10 minutes). succeeded: firstdraft compilation download <id> --output .. failed or cancelled: compile again.
    3. Still queued or running: start a fresh Project in a new folder, or cancel it with the attendee's token.
  • A compile ends with a 502, a timeout, request_outcome_unknown or compilation_status_unavailable. Do not compile again while it may still be running. With current.compilation.id in the error, wait a minute, then run firstdraft compilation status <id> --wait and download it as above once it succeeds. With no ID, compiling once more is safe: while the first one is active, First Draft refuses with 409 compilation_active and names it (row above). If anything else keeps the Project blocked, start a fresh Project.
  • analyzer_release_mismatch (foundation_plan.analysis.analyzer_release_mismatch) right after a First Draft deploy: the Plan was analyzed while the deploy was switching releases. Compile again once. Do not deploy First Draft during the workshop.
  • Many compiles fail at the same time. 30 compiles started within 5 seconds all succeeded after the 2026-10-03 capacity upgrade; 50 is untested. With more than 30 people, start compiles by table, about a minute apart.

Running and previewing

  • A native preview fails with /up returned HTTP 403, or log/bin-dev.log shows Blocked hosts: ….trycloudflare.com. The web app was started without the tunnel's host. Stop it and start it as RAILS_DEVELOPMENT_HOSTS=.trycloudflare.com bin/dev </dev/null >log/bin-dev.log 2>&1 (the attendee can type Restart the web app.).
  • On a Mac, the app's first page shows The asset 'application.css' was not found in the load path, or style changes stop showing up. The Mac has Homebrew's watchman, which stalls the CSS watcher (tailwindlabs/tailwindcss#17246). In the app folder, run npm run build:css once, then reload. If later style changes still don't show, restart the web app with WATCHMAN_SOCK=/dev/null in front of its usual start command.
  • <URL>/up fails with Could not resolve host right after cloudflared printed the address. A new quick tunnel can take up to 2 minutes to resolve. Wait and retry. Starting another tunnel does not help and counts against Cloudflare's limit on new tunnels (429 or error 1015).
  • Revyl says "Concurrency limit reached", or the helper says a preview session already exists. The last phone is still shutting down. Wait 15 to 30 seconds, run bin/<platform> preview revyl stop again (or stop it on the Revyl dashboard under Sessions), then retry. Ignore the upgrade hint.
  • A photo upload fails with KeyError: key not found: "CLOUDINARY_URL". On the laptop: in the app folder, run bash ~/.workshop/cloudinary.sh install ., then restart the web app. If it prints MISSING, the attendee runs /workshop-signin in a new session first (it redoes only what is missing). On the live app: the Render service was created without the key, so delete it (render services delete <service-id> --confirm) and create it again with the same Neon project.
  • cloudinary.sh save keeps printing INVALID. It wants three copies from the API Keys page, in this order: the copy button by API environment variable, the API Key, then the API Secret from the same row, shown with its eye button first (dots or stars are not the secret).

Changing the app

  • After an attendee limits the length of a longer text, such as "Limit posts to 280 characters", bin/ci or GitHub CI fails at Schema: active_record_doctor: "the length validator on Post.caption enforces a maximum of 280 characters but there's no schema limit". The column is text, which has no limit. Ask Claude to add the attribute it names (Post.caption here) to incorrect_length_validation's ignore_attributes in .active_record_doctor.rb, with a one-line comment, as the app's AGENTS.md says. The README no longer suggests this change.

Deploying

  • The first deploy fails with function uuidv7() does not exist. The Neon database is PostgreSQL 17, a claimable database from npx get-db or neon.new. Create a PostgreSQL 18 project (neonctl projects create --name <app> --region-id aws-us-east-2 --pg-version 18 --org-id <id> -o json, with the ID from neonctl orgs list -o json), delete the Render service (render services delete <service-id> --confirm), and deploy again with the new project's direct connection string. The Render CLI cannot change a service's environment variables.
  • Render shows the app's free services as suspended. That workspace used up its 750 free instance hours for the month, and Render suspends every free web service in it. One workspace per app avoids this, which is why the deploy notes have the attendee create a Hobby workspace named after the app (dashboard workspace switcher, then New workspace) before its first deploy.
  • Render's New workspace form shows Hobby as "Limit reached" and preselects Pro ($25/month). Render allows five Hobby workspaces per account. Do not choose Pro. Close the form and deploy into one of the attendee's existing workspaces, the one with the fewest free web services; the app then shares that workspace's free hours.
  • Render cannot see the repository after the attendee created the app's workspace. A new workspace may need its own GitHub connection (not yet tested): open https://github.com/apps/render/installations/new, or the workspace's GitHub settings on the Render dashboard, and connect it.
  • The live app is empty. Expected: sample data and demo logins are development-only. Attendees sign up there.
  • The first CI run is red, or 20 or more Dependabot pull requests appear. Harmless; ignore them.

Setup and sign-in

  • A sign-up page (Revyl, Cloudinary) shows errors or a security check. The venue network may be blocking it: have the attendee use a phone hotspot.
  • The sign-in skill has no Cloudinary step, or shows [FAIL] cloudinary: helper not installed. The laptop was set up from an older zip. Download the zip again, open its workshop-kit folder in a Local session, type continue (it redoes the handoff; give the same app name), then run /workshop-signin again in a WSL session (on a Mac, a Local session).
  • An attendee may have old First Draft packages. In Ubuntu (on a Mac, Terminal), firstdraft --version shows the CLI (0.8.2 today) and npm ls -g @firstdraft.com/claude-code shows the plugin (0.8.7 today). If either is older, run npm install --global @firstdraft.com/cli@latest @firstdraft.com/claude-code@latest there, then start a new session. With a kit zip downloaded on 2026-10-05 or later, typing continue in a Local session in its workshop-kit folder also works: setup sends old packages back to the install step (on a Mac, bash scripts/mac/setup.sh install-tools from that folder does the same). Older zips do not check for updates.

On a Mac

  • The setup's Terminal window says Need sudo access or not in the sudoers file. The attendee's macOS account is not an administrator. Someone with an administrator account must install Homebrew, or the attendee uses the Codespace guide.
  • The attendee closed the Terminal window before it said "You can close this window". Ask Claude to stop the waiting step and run bash scripts/mac/setup.sh status again; it reopens the window.
  • [FAIL] xcode-clt: installed but clang does not run. Xcode is installed but its license was never accepted. In Terminal, the attendee runs sudo xcodebuild -license accept and types their password, then types continue.
  • A Mac attendee is stuck at the Terminal's password prompt. Typing a password in Terminal shows nothing at all, not even dots, so attendees think it's broken. Have them type their Mac login password anyway and press Return; after "Sorry, try again", they retype it. Their account must be an administrator.
  • [FAIL] postgres: server is version 1X, expected 18. Another PostgreSQL (Postgres.app, or another Homebrew version) holds port 5432. Stop it (quit Postgres.app, or brew services stop postgresql@1X), then continue.
  • A new session cannot find ruby, node, psql or render, or finds older ones. Claude Desktop was not restarted after setup: quit it with Cmd-Q and reopen it. If another version manager (asdf, rbenv, nvm) is listed after the workshop lines in ~/.zshrc, its versions win; ask Claude to move the # Added by workshop setup lines to the end of ~/.zshrc and ~/.zprofile.
  • git push asks for a passphrase. The attendee already had an SSH key with a passphrase, which setup keeps. They type the passphrase in Terminal once (ssh-add --apple-use-keychain ~/.ssh/id_ed25519).
  • macOS asks whether Claude may access Downloads, Documents or Desktop. The kit or a file is there: click Allow.
  • A Mac project is in a synced folder anyway (Dropbox, iCloud Drive, or Desktop or Documents with iCloud sync), with git errors such as bad object or index.lock, files ending in 2 or (conflicted copy), or a slow web app. Ask Claude to commit and push what works. Then, in the kit's setup folder, run bash scripts/mac/setup.sh folder ~/appdev and bash scripts/mac/setup.sh handoff <name>, open a Local session in ~/appdev/<name>, and ask Claude to clone the app's GitHub repository there.

Commands

Fresh Project

For a Project that a stuck compile blocks. It copies the Plan into a new Project in a new folder; replace APP with the app folder's name. An app compiled before keeps its Plan under .firstdraft/design/.firstdraft/, so the first two lines pick that copy when it exists:

PLAN=~/APP/.firstdraft/design/.firstdraft/foundation-plan.json &&
{ [ -f "$PLAN" ] || PLAN=~/APP/.firstdraft/foundation-plan.json; } &&
mkdir ~/APP-2 && cd ~/APP-2 &&
firstdraft plan init --name "Fresh Project" &&
cp "$PLAN" .firstdraft/ &&
firstdraft plan compile

plan init only creates the new Project's ID; the copied Plan replaces its name. Then the attendee opens a new session in /home/appdev/APP-2 (WSL, Ubuntu-24.04) and continues from README step 12. On a Mac, use the projects folder (~/appdev by default) in place of ~ in the commands, and open a Local session in its APP-2.

Cancel with the attendee's token

For CLI 0.8.1. Run it where the stuck-compile commands run (the app folder, or its .firstdraft/design) after replacing COMPILATION_ID. It reads the Project ID and the attendee's saved First Draft token from their files, sends the token to First Draft only, and never prints it (-q ignores any ~/.curlrc, which could turn on verbose output):

P=$(python3 -c 'import json; print(json.load(open(".firstdraft/state.json"))["project_id"])') &&
T=$(python3 -c 'import json, os; print(json.load(open(os.path.expanduser("~/.config/firstdraft/credentials.json")))["origins"]["https://firstdraft.com"]["access_token"])') &&
printf 'Authorization: Bearer %s\n' "$T" | curl -q -sS -X POST -H @- \
  "https://firstdraft.com/v1/projects/$P/compilations/COMPILATION_ID/cancel"

A reply with "status":"cancelled" frees the Project: compile again. compilation_not_cancellable means it had already finished: check it with firstdraft compilation status.