Troubleshooting
Common issues and solutions when developing with ReadySite.
Build Errors
CGO / libsql compilation fails
Symptom: cgo: C compiler "gcc" not found or linking errors.
Cause: The database layer requires CGO for libsql/SQLite.
Fix: Install a C compiler:
# macOS
xcode-select --install
# Ubuntu/Debian
apt-get install build-essential
# Alpine (don't use for production)
apk add gcc musl-dev
Docker: Use golang:1.24-bookworm for builds, debian:bookworm-slim for runtime. Alpine won't work because CGO binaries need glibc.
go build ./hosting fails with directory exists
Symptom: Build fails because hosting/ is also a directory name.
Fix: Specify an output path:
go build -o /tmp/hosting ./hosting
Module resolution errors
Symptom: cannot find module providing package github.com/readysite/readysite/pkg/...
Fix:
go mod tidy
If using a local development copy:
go mod edit -replace github.com/readysite/readysite=../readysite
go mod tidy
Database
In-memory database loses data on restart
Symptom: All data disappears when the app restarts.
Cause: No DB_PATH or DB_URL is configured, so the auto engine defaults to in-memory.
Fix: Set a database path:
DB_PATH=./data/app.db go run ./website
Remote replica sync failures
Symptom: Data appears stale or writes fail.
Cause: The replica can't reach the primary libSQL server.
Fix:
- Check
DB_URLandDB_TOKENare correct - Verify network connectivity to the primary
- Force a sync:
models.DB.Sync()
"database is locked" errors
Symptom: Concurrent writes fail with lock errors.
Cause: SQLite allows one writer at a time. This is rare with the embedded engine but can happen under heavy load.
Fix: This usually resolves itself. If persistent, check for:
- Long-running transactions
- Unclosed database connections
- Multiple processes writing to the same file
Templates
Template not found
Symptom: template "page.html" not found or blank page.
Cause: Templates are referenced by filename only, not path.
Fix:
<!-- Correct -->
{{template "card.html" .}}
<!-- Wrong -->
{{template "partials/card.html" .}}
Templates in views/layouts/ and views/partials/ are pre-loaded at startup. All other .html files under views/ are loaded on-demand by filename.
Controller methods not accessible in templates
Symptom: {{home.Method}} returns nothing or errors.
Cause: The method might not be public (capitalized) or the controller name is wrong.
Fix:
- Ensure the method name starts with a capital letter
- Use the controller name from the factory function:
{{controllerName.Method}} - Don't use dot notation:
{{home.Method}}not{{.home.Method}}
Template changes not reflecting
Symptom: Edits to templates don't appear after refresh.
Cause: Layout and partial templates are cached at startup.
Fix: Restart the application. In development, non-layout/partial templates reload automatically.
Frontend / esbuild
HMR not working in development
Symptom: React component changes don't hot-reload.
Cause: HMR is disabled in production mode.
Fix:
- Make sure
ENVis not set toproduction - Check the browser console for WebSocket connection errors
- Verify esbuild is running (check terminal output)
esbuild "Could not resolve" errors
Symptom: Build fails with module resolution errors.
Fix:
- Run
npm installin the app directory - Check that
package.jsonincludes the dependency - Verify the
Includepaths in your bundler config match your file structure:
frontend.WithBundler(&esbuild.Config{
Entry: "frontend/index.js",
Include: []string{"frontend"}, // Must match actual directory
})
Node.js not found in Docker
Symptom: esbuild fails in production Docker container.
Fix: Add Node.js to your Dockerfile runtime stage:
FROM debian:bookworm-slim
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs
Authentication
AUTH_SECRET fatal error on startup
Symptom: FATAL: AUTH_SECRET must be set in production
Cause: ENV=production is set but AUTH_SECRET is empty or "change-me-in-production".
Fix:
# Generate and set a secret
export AUTH_SECRET=$(openssl rand -hex 32)
Session cookie not persisting
Symptom: User is logged out after every request.
Cause: The Secure flag is set but you're not using HTTPS.
Fix: In development, don't set ENV=production. The isSecure() helper detects HTTPS from direct TLS or X-Forwarded-Proto headers.
JWT validation fails after secret change
Symptom: All users are logged out after changing AUTH_SECRET.
Cause: Existing JWTs were signed with the old secret.
This is expected. Users will need to log in again.
Deployment
Server creation hangs
Symptom: launch --new hangs after creating the server.
Cause: SSH access isn't ready yet or SSH key isn't configured.
Fix:
- Ensure you have an SSH key:
~/.ssh/id_ed25519.pubor~/.ssh/id_rsa.pub - Wait — new servers can take 1-2 minutes for SSH to become available
- Check cloud provider dashboard for server status
Docker build fails on server
Symptom: Remote build fails during launch.
Cause: Server doesn't have enough memory or Docker isn't installed.
Fix:
- Use at least a
smallserver size - Build locally instead (requires Docker Desktop)
- Check server logs:
go run ./cmd/connect docker logs
Health check failures after deploy
Symptom: Container keeps restarting after deployment.
Cause: The /health endpoint isn't responding within the timeout.
Fix:
- Check container logs:
go run ./cmd/connect docker logs <container> - Verify the health endpoint exists and returns 200
- Check that
PORTenv var matches the container's listening port - Increase the health check start period if the app needs more startup time
Volume mount permissions
Symptom: App can't write to /data directory.
Cause: Volume directory doesn't exist or has wrong permissions.
Fix: Add to your setup.sh:
mkdir -p /mnt/data/myapp
chmod 755 /mnt/data/myapp
Rate Limiting
"Too many requests" during development
Symptom: Getting rate limited during local testing.
Cause: Rate limiters use r.RemoteAddr which is typically 127.0.0.1 for all local requests.
Fix: This is working as intended. Wait for the bucket to refill (typically 1 minute). For testing, restart the application to reset rate limit buckets.
AI Assistant
"API key is required" error
Symptom: AI features return assistant.ErrNoAPIKey.
Cause: No API key configured for the selected provider.
Fix: Set the API key for your provider:
- OpenAI: Configure in website settings or pass to
openai.New(key) - Anthropic: Configure in website settings or pass to
anthropic.New(key) - Testing: Use
mock.New(mock.Config{Response: "test"})— no key needed
AI responses are empty
Symptom: Chat returns empty content.
Cause: The model may have returned only tool calls (no text content).
Fix: Check resp.ToolCalls — if resp.FinishReason is "tool_calls", the model wants to execute tools before responding with text.