Diagnosing and Staging a Critical Deposit-Outage Fix: Apps Script Access Control and Multi-Endpoint Deployment Strategy
What Was Done
During a June 2026 operational session, we identified and diagnosed a complete failure of the deposit/reservation system across 11 public event pages. The root cause: two Google Apps Script endpoints (one serving 10 pages, one serving worship pages) had lost public access and were returning 403 Forbidden and 404 Not Found errors respectively. We traced the issue to deployment access controls and prepared a staged fix requiring a single console action: redeploying the affected script with Who has access = Anyone.
Technical Details: The Broken Funnel
The deposit system works via HTTP calls from event pages (hosted on S3/CloudFront) to Google Apps Script /exec endpoints. Each endpoint is a web app deployment that handles form submissions and returns JSON responses to populate the booking UI.
Affected endpoints:
https://script.google.com/macros/s/AKfycbw...44Pme8wCA/exec— serves 10 primary event pages (returning 403)https://script.google.com/macros/s/AKfycbw...AFsLWaO3/exec— serves worship event page (returning 404, indicating deleted deployment)
Why this matters: Every "Reserve Now" button across sailjada.com and queenofsandiego.com silently fails when clicked. Users see no error message—they just get a non-responsive button. This is a dark funnel leak: inbound bookings are being dropped without visibility.
Root Cause Analysis
We confirmed the issue was not a code problem by examining the Apps Script project metadata:
- Project ID:
1dDpSK8JZda7XUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5 - Project display name: Found in
appsscript.jsonat the project root - Deployment status: One deployment present (10-page endpoint) with access revoked; one deployment deleted (worship endpoint)
The deployments themselves were intact—no code changes needed. The issue was purely access control: the "Execute as" identity was no longer granting public web access.
Diagnostic Commands and Verification
We verified endpoint status directly via HTTP:
curl -i https://script.google.com/macros/s/AKfycbw.../44Pme8wCA/exec \
-X POST \
-H "Content-Type: application/json" \
-d '{"test": true}'
Result: HTTP/1.1 403 Forbidden
We also scanned all live event pages in the source repository to confirm the URLs they were calling:
grep -r "script.google.com/macros/s" \
/Users/cb/Documents/repos/sites/queenofsandiego.com/src/pages/
This confirmed both endpoints were in active use across the page templates.
Infrastructure: Apps Script Deployment Model
Google Apps Script deployments are versioned artifacts. Each deployment has:
- Deployment ID: A unique identifier (e.g.,
AKfycbw...44Pme8wCA) - Access control: Three options: "Only Me," "Anyone," or specific domain/email
- Execute-as identity: Either your Google account or the end user's account
When a deployment's access is set to "Only Me," all unauthenticated requests return 403. The Pages calling that endpoint cannot authenticate (they run in browser context with no service account), so they fail silently.
Why the second endpoint returned 404: The worship-page deployment appears to have been deleted entirely, possibly during a cleanup or failed redeploy. A 404 indicates the deployment ID no longer exists in Google's infrastructure.
The Staged Fix
The fix requires a single action in the Google Apps Script console:
- Navigate to
script.google.com - Open the project by ID:
1dDpSK8JZda7XUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5 - Go to Deploy → Manage deployments
- For the existing deployment (10-page endpoint), edit and set:
- Who has access: "Anyone"
- Execute as: "Me" (your Google account)
- Click Deploy
- For the missing worship endpoint, either restore from version history or redeploy a new instance
Key insight: If you redeploy into the same deployment slot (not creating a new version), the /exec URL remains unchanged, so the event pages need no code edits—they'll immediately start working against the newly-permissioned endpoint.
Why This Approach
Rather than refactoring deposit collection into Lambda or another service (a multi-day effort), fixing the Apps Script access control buys stability with zero downtime and zero code changes. Apps Script's version control means we can always roll back; changing access is a reversible single-console operation.
Cost-impact reasoning: Every minute the endpoints remain 403/404, we lose inbound bookings across 11 pages. The Giovanna charter and other operational tasks are important but incremental. This is the leak in the bucket.
Validation and Next Steps
Once the console redeploy is complete, we will:
- Test both
/execendpoints directly with a POST request - Load each of the 11 event pages in a browser and verify the "Reserve" button submits successfully
- Check CloudFront access logs to ensure no other downstream issues exist
- Document the deployment IDs and access config in ops notes to prevent future accidents
The entire funnel validation should take under 5 minutes once the console action is complete.
Standing Rules Reinforced
This outage highlights the importance of:
- Monitoring external service deployments: Apps Script endpoints should have a health check (ping the
/execURL every 5 minutes) - Access-control audits: Quarterly review of all script deployments to ensure "Anyone" access hasn't been accidentally revoked
- Darkness in silent failures: When a button doesn't visibly error, it's easy to miss. Add client-side error logging to all deposit endpoints