vybekiit 0.7.29 → 0.7.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +3403 -2768
- package/dist/global-guidance/language.md +7 -102
- package/dist/global-skills/add-ai/SKILL.md +7 -8
- package/dist/global-skills/add-analytics/SKILL.md +4 -7
- package/dist/global-skills/add-app-clip/SKILL.md +1 -0
- package/dist/global-skills/add-blog/SKILL.md +4 -7
- package/dist/global-skills/add-files/SKILL.md +4 -7
- package/dist/global-skills/add-images/SKILL.md +4 -7
- package/dist/global-skills/add-language/SKILL.md +5 -8
- package/dist/global-skills/add-notifications/SKILL.md +4 -7
- package/dist/global-skills/add-realtime/SKILL.md +4 -7
- package/dist/global-skills/add-search/SKILL.md +4 -7
- package/dist/global-skills/add-signin/SKILL.md +4 -8
- package/dist/global-skills/add-teams/SKILL.md +4 -7
- package/dist/global-skills/aws-cdk/SKILL.md +1 -0
- package/dist/global-skills/aws-cloudformation/SKILL.md +1 -0
- package/dist/global-skills/aws-serverless/SKILL.md +1 -0
- package/dist/global-skills/aws-serverless/references/compute-decision-edge-cases.md +77 -0
- package/dist/global-skills/better-auth-best-practices/SKILL.md +1 -0
- package/dist/global-skills/better-auth-security-best-practices/SKILL.md +1 -0
- package/dist/global-skills/building-native-ui/SKILL.md +1 -0
- package/dist/global-skills/buy-domain/SKILL.md +4 -7
- package/dist/global-skills/check-safety/SKILL.md +5 -8
- package/dist/global-skills/claimable-postgres/SKILL.md +1 -0
- package/dist/global-skills/configure-capabilities/SKILL.md +1 -1
- package/dist/global-skills/connect-account/SKILL.md +1 -1
- package/dist/global-skills/create-auth-skill/SKILL.md +1 -0
- package/dist/global-skills/doctor/SKILL.md +1 -1
- package/dist/global-skills/eas-app-stores/SKILL.md +2 -1
- package/dist/global-skills/eas-app-stores/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-hosting/SKILL.md +2 -1
- package/dist/global-skills/eas-hosting/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/SKILL.md +2 -1
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-simulator/SKILL.md +9 -1
- package/dist/global-skills/eas-simulator/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-simulator/references/logs-and-crashes.md +101 -0
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +4 -0
- package/dist/global-skills/eas-update/SKILL.md +2 -1
- package/dist/global-skills/eas-update/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-update-insights/SKILL.md +2 -1
- package/dist/global-skills/eas-update-insights/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-workflows/SKILL.md +2 -1
- package/dist/global-skills/eas-workflows/agents/openai.yaml +1 -1
- package/dist/global-skills/email-best-practices/SKILL.md +1 -0
- package/dist/global-skills/expo-animation/SKILL.md +2 -1
- package/dist/global-skills/expo-api-routes/SKILL.md +1 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +2 -1
- package/dist/global-skills/expo-brownfield/SKILL.md +2 -1
- package/dist/global-skills/expo-cicd-workflows/SKILL.md +1 -0
- package/dist/global-skills/expo-data-fetching/SKILL.md +2 -1
- package/dist/global-skills/expo-deployment/SKILL.md +1 -0
- package/dist/global-skills/expo-design-system/SKILL.md +2 -1
- package/dist/global-skills/expo-dev-client/SKILL.md +2 -1
- package/dist/global-skills/expo-dom/SKILL.md +2 -1
- package/dist/global-skills/expo-examples/SKILL.md +2 -1
- package/dist/global-skills/expo-migrate-module/SKILL.md +2 -1
- package/dist/global-skills/expo-module/SKILL.md +2 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +2 -1
- package/dist/global-skills/expo-observe/SKILL.md +1 -0
- package/dist/global-skills/expo-overview/SKILL.md +2 -1
- package/dist/global-skills/expo-project-structure/SKILL.md +2 -1
- package/dist/global-skills/expo-router/SKILL.md +2 -1
- package/dist/global-skills/expo-skill-eval/SKILL.md +1 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +1 -0
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +1 -0
- package/dist/global-skills/expo-ui/SKILL.md +2 -1
- package/dist/global-skills/expo-upgrade/SKILL.md +2 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +2 -1
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +1 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +1 -0
- package/dist/global-skills/firebase-ai-logic-basics/references/tts_generation.md +676 -0
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +1 -0
- package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +61 -23
- package/dist/global-skills/firebase-basics/SKILL.md +2 -0
- package/dist/global-skills/firebase-basics/references/android_setup.md +165 -23
- package/dist/global-skills/firebase-crashlytics/SKILL.md +1 -0
- package/dist/global-skills/firebase-crashlytics/references/android_setup.md +147 -119
- package/dist/global-skills/firebase-data-connect/SKILL.md +1 -0
- package/dist/global-skills/firebase-data-connect/reference/sdk_android.md +81 -25
- package/dist/global-skills/firebase-firestore/SKILL.md +1 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +70 -44
- package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +63 -27
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +1 -0
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +1 -0
- package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +87 -95
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +1 -0
- package/dist/global-skills/firestore-rules-creation/SKILL.md +1 -0
- package/dist/global-skills/go-live/SKILL.md +7 -7
- package/dist/global-skills/harden/SKILL.md +7 -10
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -0
- package/dist/global-skills/manifest.json +2 -1
- package/dist/global-skills/mongodb-atlas-stream-processing/SKILL.md +1 -0
- package/dist/global-skills/mongodb-connection/SKILL.md +1 -0
- package/dist/global-skills/mongodb-mcp-setup/SKILL.md +1 -0
- package/dist/global-skills/mongodb-natural-language-querying/SKILL.md +1 -0
- package/dist/global-skills/mongodb-qe-size-estimation/SKILL.md +224 -0
- package/dist/global-skills/mongodb-query-optimizer/SKILL.md +1 -0
- package/dist/global-skills/mongodb-schema-design/SKILL.md +1 -0
- package/dist/global-skills/mongodb-search-and-ai/SKILL.md +1 -0
- package/dist/global-skills/native-data-fetching/SKILL.md +1 -0
- package/dist/global-skills/neon/SKILL.md +18 -5
- package/dist/global-skills/neon-ai-gateway/SKILL.md +1 -0
- package/dist/global-skills/neon-auth/SKILL.md +1 -0
- package/dist/global-skills/neon-functions/SKILL.md +12 -0
- package/dist/global-skills/neon-functions/references/native-binaries.md +188 -0
- package/dist/global-skills/neon-object-storage/SKILL.md +1 -0
- package/dist/global-skills/neon-postgres/SKILL.md +1 -0
- package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -0
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -0
- package/dist/global-skills/onboarding/SKILL.md +14 -13
- package/dist/global-skills/plan-my-idea/SKILL.md +1 -1
- package/dist/global-skills/publish-app/SKILL.md +1 -1
- package/dist/global-skills/publish-extension/SKILL.md +1 -1
- package/dist/global-skills/resend/SKILL.md +2 -1
- package/dist/global-skills/resend/references/webhooks.md +2 -0
- package/dist/global-skills/reset-password/SKILL.md +4 -6
- package/dist/global-skills/save-data/SKILL.md +3 -0
- package/dist/global-skills/sentry-sdk-setup/SKILL.md +1 -0
- package/dist/global-skills/sentry-workflow/SKILL.md +1 -0
- package/dist/global-skills/setup-email/SKILL.md +7 -8
- package/dist/global-skills/setup-payments/SKILL.md +10 -12
- package/dist/global-skills/setup-sms/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-email-link/SKILL.md +4 -6
- package/dist/global-skills/sign-in-with-google/SKILL.md +14 -13
- package/dist/global-skills/sign-in-with-phone/SKILL.md +5 -7
- package/dist/global-skills/stripe-best-practices/SKILL.md +2 -1
- package/dist/global-skills/stripe-best-practices/references/billing.md +2 -0
- package/dist/global-skills/stripe-best-practices/references/payments.md +1 -1
- package/dist/global-skills/stripe-best-practices/references/tax.md +2 -2
- package/dist/global-skills/supabase/CHANGELOG.md +19 -0
- package/dist/global-skills/supabase/SKILL.md +1 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -0
- package/dist/global-skills/track-errors/SKILL.md +12 -13
- package/dist/global-skills/update-kit/SKILL.md +1 -1
- package/dist/global-skills/upgrading-expo/SKILL.md +1 -0
- package/dist/global-skills/use-dom/SKILL.md +1 -0
- package/dist/global-skills/use-railway/SKILL.md +6 -5
- package/dist/global-skills/use-railway/references/configure.md +34 -1
- package/dist/global-skills/use-railway/references/iac.md +2 -0
- package/dist/global-skills/use-railway/references/tracing.md +89 -44
- package/dist/global-skills/vercel-composition-patterns/SKILL.md +1 -0
- package/dist/global-skills/vercel-react-best-practices/SKILL.md +1 -0
- package/dist/global-skills/vybekiitReferences/backend/AGENTS.md +11 -3
- package/dist/global-skills/vybekiitReferences/backend/agent/goal-index.md +1 -1
- package/dist/global-skills/vybekiitReferences/backend/agent/goal-routes.json +229 -0
- package/dist/global-skills/vybekiitReferences/backend/agent/mcp-setup.md +11 -2
- package/dist/global-skills/vybekiitReferences/backend/agent/session-bootstrap.md +1 -1
- package/dist/global-skills/vybekiitReferences/backend/agent/tech-references.md +1 -1
- package/dist/global-skills/vybekiitReferences/backend/language.md +7 -102
- package/dist/global-skills/vybekiitReferences/backend/platform-skills/deploy-railway-vybekiit.md +2 -2
- package/dist/global-skills/vybekiitReferences/backend/platform-skills/extend-capabilities-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/backend/platform-skills/mongodb-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/extension/AGENTS.md +11 -3
- package/dist/global-skills/vybekiitReferences/extension/agent/goal-index.md +1 -1
- package/dist/global-skills/vybekiitReferences/extension/agent/goal-routes.json +239 -0
- package/dist/global-skills/vybekiitReferences/extension/agent/mcp-setup.md +10 -1
- package/dist/global-skills/vybekiitReferences/extension/agent/session-bootstrap.md +1 -1
- package/dist/global-skills/vybekiitReferences/extension/agent/tech-references.md +1 -1
- package/dist/global-skills/vybekiitReferences/extension/agent/ui-sources.md +11 -8
- package/dist/global-skills/vybekiitReferences/extension/language.md +7 -92
- package/dist/global-skills/vybekiitReferences/extension/platform-skills/browser-automation-vybekiit.md +9 -1
- package/dist/global-skills/vybekiitReferences/extension/platform-skills/env-secrets-vybekiit.md +1 -0
- package/dist/global-skills/vybekiitReferences/extension/platform-skills/extend-capabilities-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/extension/platform-skills/observability-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/extension/platform-skills/sentry-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/AGENTS.md +27 -12
- package/dist/global-skills/vybekiitReferences/mobile/agent/goal-index.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/agent/goal-routes.json +279 -0
- package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-setup.md +10 -1
- package/dist/global-skills/vybekiitReferences/mobile/agent/session-bootstrap.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/agent/tech-references.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/agent/ui-sources.mobile.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/language.md +7 -93
- package/dist/global-skills/vybekiitReferences/mobile/platform-skills/env-secrets-vybekiit.md +1 -0
- package/dist/global-skills/vybekiitReferences/mobile/platform-skills/extend-capabilities-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/platform-skills/i18n-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/platform-skills/observability-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/platform-skills/sentry-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/mobile/platform-skills/ui-port-from-web-vybekiit.md +2 -2
- package/dist/global-skills/vybekiitReferences/spa/AGENTS.md +11 -3
- package/dist/global-skills/vybekiitReferences/spa/agent/goal-index.md +1 -1
- package/dist/global-skills/vybekiitReferences/spa/agent/goal-routes.json +267 -0
- package/dist/global-skills/vybekiitReferences/spa/agent/mcp-setup.md +10 -1
- package/dist/global-skills/vybekiitReferences/spa/agent/session-bootstrap.md +1 -1
- package/dist/global-skills/vybekiitReferences/spa/agent/ui-sources.md +11 -8
- package/dist/global-skills/vybekiitReferences/spa/language.md +7 -11
- package/dist/global-skills/vybekiitReferences/web/AGENTS.md +15 -30
- package/dist/global-skills/vybekiitReferences/web/agent/goal-index.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/agent/goal-routes.json +366 -0
- package/dist/global-skills/vybekiitReferences/web/agent/mcp-setup.md +11 -2
- package/dist/global-skills/vybekiitReferences/web/agent/session-bootstrap.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/language.md +7 -102
- package/dist/global-skills/vybekiitReferences/web/platform-skills/ai-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/analytics-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/assets-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/better-auth-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/browser-automation-vybekiit.md +9 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/cms-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/compliance-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-github-pages-vybekiit.md +2 -2
- package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-railway-vybekiit.md +2 -2
- package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-vercel-vybekiit.md +2 -2
- package/dist/global-skills/vybekiitReferences/web/platform-skills/env-secrets-vybekiit.md +1 -0
- package/dist/global-skills/vybekiitReferences/web/platform-skills/extend-capabilities-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/i18n-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/jobs-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/kv-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/lemon-squeezy-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/mongodb-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/notifications-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/observability-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/paypal-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/realtime-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/registrar-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/search-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/sentry-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/seo-vybekiit.md +1 -3
- package/dist/global-skills/vybekiitReferences/web/platform-skills/supabase-vybekiit.md +1 -1
- package/dist/global-skills/vybekiitReferences/web/platform-skills/tenancy-vybekiit.md +1 -1
- package/dist/global-skills/web-to-native/SKILL.md +1 -0
- package/dist/global-skills/workers-best-practices/SKILL.md +4 -3
- package/dist/global-skills/workers-best-practices/references/configuration.md +1 -1
- package/dist/global-skills/workers-best-practices/references/platform-apis.md +5 -5
- package/dist/global-skills/workers-best-practices/references/runtime-patterns.md +1 -1
- package/dist/global-skills/wrangler/SKILL.md +27 -24
- package/dist/global-skills/xcode-project-setup/SKILL.md +1 -0
- package/package.json +10 -8
|
@@ -278,6 +278,36 @@ railway domain delete example.com --service <service> --yes --json
|
|
|
278
278
|
|
|
279
279
|
Domain deletion is destructive. Confirm the domain and service before running it.
|
|
280
280
|
|
|
281
|
+
## Webhooks
|
|
282
|
+
|
|
283
|
+
Project webhooks POST a JSON payload to a URL whenever a chosen deployment, monitor, or volume-alert event happens anywhere in the project. They are project-scoped, not per service or environment, and are managed with five MCP tools. There is no `railway webhook` CLI command. Resolve the project ID from `railway status --json` or `list-projects` first.
|
|
284
|
+
|
|
285
|
+
| Tool | Purpose |
|
|
286
|
+
|---|---|
|
|
287
|
+
| `list-webhooks` | Every webhook in the project: URL, `eventTypes`, `includePreviewEnvironments`, the names of its custom headers (`headerNames`), and the `id` the other tools take |
|
|
288
|
+
| `create-webhook` | `url` plus optional `eventTypes` (defaults to `Deployment.failed`, `Deployment.crashed`, `Deployment.oom_killed`), `includePreviewEnvironments` (defaults to `true`), and `headers` |
|
|
289
|
+
| `update-webhook` | `webhookId` plus any of `url`, `eventTypes`, `includePreviewEnvironments`, `headers`. Only the fields passed change; `eventTypes` and `headers` each replace the whole set |
|
|
290
|
+
| `test-webhook` | POST a sample event and report the HTTP status. Pass `url` (and optional `headers`) to try a new endpoint, or `webhookId` to send to an existing webhook with its stored URL and headers. Nothing is stored |
|
|
291
|
+
| `delete-webhook` | Remove a webhook by `webhookId`. Destructive; confirm the URL with the user first |
|
|
292
|
+
|
|
293
|
+
Discord and Slack incoming-webhook URLs are detected and receive a formatted message instead of the raw JSON. Run `test-webhook` before `create-webhook`: Railway treats anything outside `2xx`/`3xx` as a failed delivery, and a dead endpoint is paused for 24 hours after repeated failures.
|
|
294
|
+
|
|
295
|
+
```text
|
|
296
|
+
Create webhook for project <project-id>: url https://hooks.example.com/railway, eventTypes Deployment.failed Deployment.crashed, headers { "Authorization": "Bearer <token>" }
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Custom headers
|
|
300
|
+
|
|
301
|
+
A webhook can carry up to 20 custom HTTP headers, sent with every delivery and with `test-webhook`. Use them for whatever the receiver needs to trust or route the request: an `Authorization` bearer token, an API key, a shared secret the receiver compares, a routing header. This replaces the old advice of hiding a secret in the URL, which still works but leaks into logs more easily.
|
|
302
|
+
|
|
303
|
+
- **Values are write-only.** They are encrypted at rest and never returned: `list-webhooks` and every other tool's output carry `headerNames` only. Keep the value in the user's secret store; Railway cannot show it again.
|
|
304
|
+
- **`create-webhook` and `test-webhook`** take `headers` as a name-to-value map.
|
|
305
|
+
- **`update-webhook` replaces the whole set.** Every header not listed is removed and `{}` clears them all. A `null` value keeps the stored value for that name, so a secret survives a change without being resent: `{ "Authorization": null, "X-Env": "prod" }` keeps the token and sets `X-Env`. A URL-only update carries the stored headers forward automatically.
|
|
306
|
+
- **`test-webhook` with `webhookId`** sends the stored headers; any `headers` passed alongside override the stored one of the same name and the rest are still sent. Headers are validated before the request goes out, so a bad name gets a clear error instead of a `0` status.
|
|
307
|
+
- **Name rules.** RFC 9110 token characters, up to 128 characters; values up to 4096 characters with no CR or LF. `Host`, `Content-Type`, `Content-Length` and the hop-by-hop headers (`Transfer-Encoding`, `Connection`, `Keep-Alive`, `Upgrade`, `TE`, `Trailer`, `Expect`) are refused, as is any name starting with `proxy-` or `x-railway-`. Two names differing only by case count as a duplicate. The dashboard form applies the same rules inline and disables Save until a bad row is fixed.
|
|
308
|
+
|
|
309
|
+
Without MCP, the same fields are on the GraphQL API: `headers` inside the webhook channel config of `notificationRuleCreate` / `notificationRuleUpdate` (a `null` value keeps the stored one there too), and `webhookTest(url, payload, headers: [WebhookHeaderInput!], notificationRuleId)`. Inspect them with `railway api describe`.
|
|
310
|
+
|
|
281
311
|
## Networking commands
|
|
282
312
|
|
|
283
313
|
### Private networking
|
|
@@ -365,10 +395,13 @@ While active, browser visitors must pass a check. Non-browser API clients and we
|
|
|
365
395
|
- **Outbound allowlist still sees old IPs**: redeploy after enabling/disabling Static Outbound IPs
|
|
366
396
|
- **IPv6 still disabled**: commit the staged environment change and wait for redeploy
|
|
367
397
|
- **CDN appears ineffective**: check `x-cache`, `age`, cache headers, `Set-Cookie`, `Authorization`, method, and response size
|
|
398
|
+
- **Webhook header rejected**: the name is reserved (`Host`, `Content-Type`, `Content-Length`, hop-by-hop), starts with `proxy-` or `x-railway-`, duplicates another name ignoring case, or the value has a newline; rename it or drop it, and stay under 20 headers
|
|
399
|
+
- **Webhook headers disappeared after an update**: `update-webhook` replaces the whole `headers` set, so a map without a name removes it; pass `null` for names to keep, or omit `headers` entirely
|
|
368
400
|
- **WAF breaks API clients**: Under Attack Mode blocks non-browser traffic; disable it or scope protection to browser-facing services
|
|
369
401
|
- **Multi-region patch ignored**: verify region names match the exact identifiers (`us-west2`, `us-east4-eqdc4a`, `europe-west4-drams3a`, `asia-southeast1-eqsg3a`)
|
|
370
402
|
|
|
371
403
|
## Validated against
|
|
372
404
|
|
|
373
|
-
- Docs: [environment.md](https://docs.railway.com/cli/environment), [variable.md](https://docs.railway.com/cli/variable), [domain.md](https://docs.railway.com/cli/domain), [tcp-proxy.md](https://docs.railway.com/cli/tcp-proxy), [private-network.md](https://docs.railway.com/cli/private-network), [outbound-network.md](https://docs.railway.com/cli/outbound-network), [cdn.md](https://docs.railway.com/cli/cdn), [waf.md](https://docs.railway.com/cli/waf)
|
|
405
|
+
- Docs: [environment.md](https://docs.railway.com/cli/environment), [variable.md](https://docs.railway.com/cli/variable), [domain.md](https://docs.railway.com/cli/domain), [tcp-proxy.md](https://docs.railway.com/cli/tcp-proxy), [private-network.md](https://docs.railway.com/cli/private-network), [outbound-network.md](https://docs.railway.com/cli/outbound-network), [cdn.md](https://docs.railway.com/cli/cdn), [waf.md](https://docs.railway.com/cli/waf), [webhooks.md](https://docs.railway.com/observability/webhooks)
|
|
406
|
+
- Platform source (railwayapp/mono): `packages/backboard/src/handlers/http/routes/mcp/tools/webhooks.ts` (webhook MCP tools), `packages/backboard/src/controllers/notifications/validation.ts` (`validateWebhookHeaders`), `packages/backboard/src/graphql/v2/schema/schema.graphql` (`webhookTest`, `WebhookHeaderInput`)
|
|
374
407
|
- CLI source: [environment/mod.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/environment/mod.rs), [environment/edit.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/environment/edit.rs), [variable.rs](https://github.com/railwayapp/cli/blob/v5.49.1/src/commands/variable.rs), [domain.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/domain.rs), [tcp_proxy.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/tcp_proxy.rs), [private_network.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/private_network.rs), [outbound_networking.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/outbound_networking.rs), [cdn.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/cdn.rs), [waf.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/waf.rs)
|
|
@@ -113,6 +113,8 @@ const media = bucket("media", { region: "iad" });
|
|
|
113
113
|
const backend = group("Backend", [api, worker, db]);
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
+
A traced service also carries `tracing: { enabled: true, autoInstrumentation: true }`, which `config pull` renders but the `service()` helper does not pass through yet; see [Infrastructure as code in tracing.md](tracing.md#infrastructure-as-code) before applying a plan that touches `tracing`.
|
|
117
|
+
|
|
116
118
|
Advanced placement can map regions to replica counts:
|
|
117
119
|
|
|
118
120
|
```ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tracing
|
|
2
2
|
|
|
3
|
-
Trace a request from Railway's edge through a service and into the services it calls.
|
|
3
|
+
Trace a request from Railway's edge through a service and into the services it calls. Tracing is switched on per service **and per environment**: with the `set-service-tracing` MCP tool, `railway trace enable`, or the **Tracing setup** drawer on the project's **Traces** tab. Read the result with `list-traces` and `get-trace`, or on the same tab.
|
|
4
4
|
|
|
5
5
|
Tracing is a preview feature. If the project has no **Traces** tab, the account needs **Tracing** enabled in Priority Boarding first.
|
|
6
6
|
|
|
@@ -13,56 +13,89 @@ Spans from inside the service only appear once the service exports them, through
|
|
|
13
13
|
|
|
14
14
|
## Enable tracing
|
|
15
15
|
|
|
16
|
-
Tracing
|
|
16
|
+
Tracing is two switches on each service instance, so they are set per service and per environment. `tracingEnabled` makes the edge trace requests to the service and gives its next deploy the OpenTelemetry variables below; `autoInstrumentationEnabled` attaches eBPF probes to the service's processes and only does anything while tracing is on. There is no project-wide default and no sample rate: every client-facing request to a traced service is traced. Enabling a service in `production` says nothing about `staging`, so check and set each environment the user cares about.
|
|
17
17
|
|
|
18
|
-
**Dashboard:** open the **Traces** tab → **Tracing setup**.
|
|
18
|
+
**Dashboard:** open the **Traces** tab → **Tracing setup**. The drawer lists the services of the environment the dashboard is on (the subtitle names it); each row's **Traced** switch and **Automatic instrumentation** / **Manual instrumentation** choice apply to that environment only. Switch environment to configure another. The service's **Settings → Tracing** section links to the same drawer.
|
|
19
19
|
|
|
20
|
-
**Agent path:**
|
|
20
|
+
**Agent path:** two MCP tools read and change these settings, and `railway trace` does the same from the CLI. Resolve IDs from the URL or `railway status --json` first, and read before writing. Both tools use the `production` environment when `environmentId` is omitted, so pass it whenever the user is looking at another environment. On a Railway cloud agent in a dashboard chat session the `railway` CLI is unauthenticated, so resolve IDs with `list-services` and stay on the MCP tools throughout.
|
|
21
21
|
|
|
22
22
|
| Tool | Access | Purpose |
|
|
23
23
|
|---|---|---|
|
|
24
|
-
| `get-tracing` | viewer | The
|
|
25
|
-
| `set-service-tracing` | member | `tracingEnabled` `
|
|
26
|
-
| `set-project-tracing` | member | `tracingEnabled` sets the project default for every service without an override; `sampleRate` is the fraction of client-facing requests the edge traces, `0..1`, `null` resets to Railway's default of every request. Each is optional |
|
|
24
|
+
| `get-tracing` | viewer | The `environment` and, per service in it, `tracingEnabled`, `autoInstrumentationEnabled` and whether it is `autoInstrumentationActive` (both on). Pass `serviceId` for one service, omit it for every service in the environment |
|
|
25
|
+
| `set-service-tracing` | member | `tracingEnabled` and `autoInstrumentationEnabled` for one service in one environment. Each is optional and independent; omit what should stay as it is. Returns the service's state in that environment |
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
Both take `projectId` and an optional `environmentId`. `describe-service` reports the same tracing state for one service in the environment it was asked about.
|
|
29
28
|
|
|
30
29
|
```text
|
|
31
|
-
Get tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb
|
|
30
|
+
Get tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb in environment <environment-id>
|
|
32
31
|
```
|
|
33
32
|
|
|
34
33
|
```text
|
|
35
|
-
Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>: tracingEnabled true
|
|
34
|
+
Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>, environment <environment-id>: tracingEnabled true
|
|
36
35
|
```
|
|
37
36
|
|
|
38
37
|
```text
|
|
39
|
-
Set
|
|
38
|
+
Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>, environment <environment-id>: autoInstrumentationEnabled true
|
|
40
39
|
```
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
`set-service-tracing` warns when it switches auto-instrumentation on for a service whose tracing is off: the switch does nothing until tracing is enabled too. Without Railway MCP or `railway trace`, the public `serviceInstanceUpdate` mutation sets the same fields through `railway api`, and the environment's service instances carry them for reading; see [request.md](request.md). That fallback needs an authenticated CLI, which a cloud agent's chat session does not have.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
railway api \
|
|
45
|
+
'mutation traceInstance($serviceId: String!, $environmentId: String!) {
|
|
46
|
+
serviceInstanceUpdate(serviceId: $serviceId, environmentId: $environmentId,
|
|
47
|
+
input: { tracingEnabled: true, autoInstrumentationEnabled: false })
|
|
48
|
+
}' \
|
|
49
|
+
--variables '{"serviceId":"<service-id>","environmentId":"<environment-id>"}'
|
|
50
|
+
|
|
51
|
+
railway api \
|
|
52
|
+
'query tracing($id: String!) {
|
|
53
|
+
environment(id: $id) { serviceInstances { edges { node {
|
|
54
|
+
serviceId serviceName tracingEnabled autoInstrumentationEnabled
|
|
55
|
+
} } } }
|
|
56
|
+
}' \
|
|
57
|
+
--variables '{"id":"<environment-id>"}'
|
|
44
58
|
```
|
|
45
59
|
|
|
46
|
-
The
|
|
60
|
+
The older `Project` and `Service` tracing fields still exist as deprecated stubs: `projectUpdate(tracingEnabled)` switches every instance in the project, `serviceUpdate(tracingEnabled)` the service in every environment, and `tracingSampleRate` is ignored. Don't use them; they flip environments the user didn't mention.
|
|
47
61
|
|
|
48
|
-
**CLI:** `railway trace` (aliases `traces`, `tracing`) sets the same
|
|
62
|
+
**CLI:** `railway trace` (aliases `traces`, `tracing`) sets the same switches, in one environment at a time: the linked one, or `--environment <name>`. This needs a CLI release newer than 5.62.1. An older CLI still runs `railway trace enable`, but through the deprecated service field, so it sets the service in every environment, and its `inherit`, `--project-default` and `--sample-rate` belong to the model that is gone. Use the CLI when the user works in a linked repo or wants exact command output; on a cloud agent's chat session stay on MCP.
|
|
49
63
|
|
|
50
64
|
```bash
|
|
51
|
-
railway trace status
|
|
52
|
-
railway trace
|
|
65
|
+
railway trace status # linked service in the linked environment
|
|
66
|
+
railway trace status --all # every service in the environment, last edge/app span
|
|
67
|
+
railway trace enable --service <service> # trace one service in the linked environment
|
|
53
68
|
railway trace enable --auto-instrument # tracing plus OBI for the linked service
|
|
54
|
-
railway trace enable --
|
|
55
|
-
railway trace disable --auto-instrument #
|
|
56
|
-
railway trace inherit # follow the project default again
|
|
69
|
+
railway trace enable --all --environment staging # every service in staging
|
|
70
|
+
railway trace disable --auto-instrument # tracing and OBI off
|
|
57
71
|
```
|
|
58
72
|
|
|
59
|
-
|
|
73
|
+
`--all` and `--service` are mutually exclusive. Pass `--project <id> --environment <name>` together when nothing is linked. `--json` prints one document with `environment: { id, name }` and the service state. Changing tracing needs a user or workspace token; a project token (`RAILWAY_TOKEN`) can only read. The CLI has no switch for auto-instrumentation alone: `railway trace disable --auto-instrument` followed by `railway trace enable` leaves tracing on and OBI off, or use `set-service-tracing` with only `autoInstrumentationEnabled`.
|
|
60
74
|
|
|
61
75
|
What happens next:
|
|
62
76
|
|
|
63
|
-
- The edge starts tracing requests to the service's domains within seconds.
|
|
77
|
+
- The edge starts tracing requests to the service's domains in that environment within seconds.
|
|
64
78
|
- Automatic instrumentation reaches the running containers within about a minute. No redeploy.
|
|
65
|
-
- The OpenTelemetry variables below are added on the **next deploy
|
|
79
|
+
- The OpenTelemetry variables below are added on the **next deploy** in that environment. An app with an SDK exports nothing until it is redeployed: `railway redeploy --service <service> --yes`.
|
|
80
|
+
|
|
81
|
+
### Infrastructure as code
|
|
82
|
+
|
|
83
|
+
The environment config carries the same two switches as `services[<id>].tracing: { enabled, autoInstrumentation }`, so tracing is part of what `railway config pull`, `plan` and `apply` manage (see [iac.md](iac.md)). Railway serialises only the switches that are on: an untraced service has no `tracing` block, and `enabled: false` is the same as leaving it out. `railway config pull` renders the block for a traced service:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
const api = service("api", {
|
|
87
|
+
source: github("owner/repo", { branch: "main" }),
|
|
88
|
+
tracing: { enabled: true, autoInstrumentation: true },
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
A plan shows a tracing change as a `resource.update` with `field: "tracing"`. Turning `enabled` on or off has `deployEffect: deploy`, because the `OTEL_*` variables land with a deploy; an `autoInstrumentation`-only change is `deployEffect: none` and reaches the running containers live. A new service carries `tracing` on its create.
|
|
93
|
+
|
|
94
|
+
**Current limitation: the SDKs don't carry `tracing` yet.** The TypeScript `service()` helper, and the Python and Go ones, whitelist their config keys and `tracing` is not among them, so a `tracing:` the user writes in `railway.ts` is dropped before the CLI sees it and never applies. The other direction is worse: a compiled config with no `tracing` block asks to remove it, so `railway config plan` against a service that is traced shows a `tracing` update with `after: null` and `deployEffect: deploy`, and `railway config apply` turns tracing off and redeploys. Until the SDKs ship the field:
|
|
95
|
+
|
|
96
|
+
- Set tracing with `set-service-tracing`, `railway trace` or the dashboard, not in `railway.ts`, and say why when the user asks for it in config.
|
|
97
|
+
- Read every plan for a `tracing` change nobody authored, and don't apply one. `railway config pull` reproduces the block, but the SDK drops it again on the next plan, so pulling doesn't fix it.
|
|
98
|
+
- If an apply already disabled tracing, re-enable it with `set-service-tracing`; the redeploy for the variables follows.
|
|
66
99
|
|
|
67
100
|
## Choose how the service exports spans
|
|
68
101
|
|
|
@@ -80,7 +113,7 @@ Pick one per service. Running an SDK in a service that also has automatic instru
|
|
|
80
113
|
|
|
81
114
|
## Instrument with an OpenTelemetry SDK
|
|
82
115
|
|
|
83
|
-
When tracing is on for a service, its next deploy gets these variables. They show up in the service's **Variables** tab alongside the other Railway-provided variables and every OpenTelemetry SDK reads them, so an SDK configured without an explicit endpoint exports to Railway:
|
|
116
|
+
When tracing is on for a service in an environment, its next deploy there gets these variables. They show up in the service's **Variables** tab alongside the other Railway-provided variables and every OpenTelemetry SDK reads them, so an SDK configured without an explicit endpoint exports to Railway:
|
|
84
117
|
|
|
85
118
|
| Variable | Value |
|
|
86
119
|
|---|---|
|
|
@@ -89,8 +122,6 @@ When tracing is on for a service, its next deploy gets these variables. They sho
|
|
|
89
122
|
| `OTEL_EXPORTER_OTLP_HEADERS` | A header the receiver requires on every export |
|
|
90
123
|
| `OTEL_SERVICE_NAME` | The Railway service name |
|
|
91
124
|
| `OTEL_SERVICE_VERSION` | The commit SHA, or the deployment ID for image and CLI deploys |
|
|
92
|
-
| `OTEL_TRACES_SAMPLER` | `parentbased_traceidratio`, only when the project set its own sample rate |
|
|
93
|
-
| `OTEL_TRACES_SAMPLER_ARG` | The project's sample rate as a fraction, only when the project set its own sample rate |
|
|
94
125
|
|
|
95
126
|
Rules the agent must apply:
|
|
96
127
|
|
|
@@ -101,7 +132,7 @@ Rules the agent must apply:
|
|
|
101
132
|
Set variables for project <project-id>, service <service-id>: OTEL_METRICS_EXPORTER=none, OTEL_LOGS_EXPORTER=none, skipDeploys true
|
|
102
133
|
```
|
|
103
134
|
|
|
104
|
-
- **User variables win.** A service that sets its own `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (for example to keep exporting to its own collector) gets none of the tracing variables, and its spans don't reach the Traces tab; edge spans still do.
|
|
135
|
+
- **User variables win.** A service that sets its own `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (for example to keep exporting to its own collector) gets none of the tracing variables, and its spans don't reach the Traces tab; edge spans still do. Railway sets no sampler variables, so a sampler the service configures is the only one in play. Check `railway variable list --service <service> --json` before assuming the provided values apply.
|
|
105
136
|
- **Load the SDK first.** Instrumentation libraries (`@opentelemetry/auto-instrumentations-node`, `opentelemetry-instrumentation-*` and the like) patch libraries at import time, so the SDK must be loaded before the app's modules: a `--require`/`--import` flag in the start command, `NODE_OPTIONS`, a Python `opentelemetry-instrument` wrapper, a Java `-javaagent`, and so on. Set it with `railway environment edit --service-config <service> deploy.startCommand "<command>"` or as a variable; see [deploy.md](deploy.md).
|
|
106
137
|
- **Keep W3C Trace Context propagation on** (the SDK default in most languages; Go requires setting the propagator explicitly) so the service continues the edge's trace instead of starting its own.
|
|
107
138
|
- **Don't override `OTEL_SERVICE_NAME`** unless the user wants spans attributed under a different name than the Railway service.
|
|
@@ -113,7 +144,15 @@ Per-language install steps, framework notes, and a custom-span example are in th
|
|
|
113
144
|
Instrumentation libraries give a trace its skeleton: a server span per request and a client span per call a library recognises. On its own that is barely better than automatic instrumentation. The value comes from spans the app opens itself around the units of work its authors think in. When adding tracing to a codebase, or when asked what to instrument, cover these three layers, in this order:
|
|
114
145
|
|
|
115
146
|
1. **Inbound work.** One span per HTTP handler, gRPC method, queue or job consumer invocation, cron run and WebSocket message. The HTTP and gRPC server instrumentations usually cover handlers. Consumers, cron and background jobs are not covered by the edge or by most instrumentations, so wrap each message or run in its own span (kind `CONSUMER` or `INTERNAL`) and, where the message carries a `traceparent`, continue that context so the trace links back to the producer. Without this, background work is invisible or shows up as orphaned client spans.
|
|
116
|
-
2. **I/O: database queries, cache calls, outgoing HTTP and gRPC calls, queue publishes.** This is where latency and failures hide. Use the driver or client instrumentation where one exists. Where none does (a raw socket client, a vendor SDK the instrumentations don't know), wrap the call in a `CLIENT` span with the standard `db.*`, `server.address` or `url.full` attributes. Every remote call should be visible as its own span.
|
|
147
|
+
2. **I/O: database queries, cache calls, outgoing HTTP and gRPC calls, queue publishes.** This is where latency and failures hide. Use the driver or client instrumentation where one exists. Where none does (a raw socket client, a vendor SDK the instrumentations don't know), wrap the call in a `CLIENT` span with the standard `db.*`, `server.address` or `url.full` attributes. Every remote call should be visible as its own span. List every database driver or ORM, cache, HTTP and queue client in the dependency manifest and check each one, because the bundles miss common ones:
|
|
148
|
+
- **Node.js**: `@opentelemetry/auto-instrumentations-node` covers `pg`, `mysql2`, `ioredis`, `mongodb`, `mongoose`, `knex` and `undici`/`http`, but not Prisma (add `@prisma/instrumentation` to the SDK's instrumentations) and not postgres.js, Drizzle on postgres.js, `Bun.sql` or the Neon serverless driver (no instrumentation exists; wrap queries in a `CLIENT` span with `db.system`, `db.namespace`, `db.operation.name`). An app written as ES modules needs the `@opentelemetry/instrumentation/hook.mjs` loader, or imported drivers stay unpatched while the `http` server span still appears.
|
|
149
|
+
- **Python**: `opentelemetry-distro` alone instruments nothing; run `opentelemetry-bootstrap -a install` so the instrumentations for the installed drivers (`psycopg2`, `asyncpg`, `SQLAlchemy`, `redis`, `pymongo`, `requests`, `httpx`) are installed too.
|
|
150
|
+
- **Go**: nothing is automatic. Wrap `database/sql` with `otelsql`, pgx with `otelpgx`, go-redis with `redisotel`, HTTP clients with `otelhttp.NewTransport`.
|
|
151
|
+
- **Rust**: `sqlx` emits tracing events, not spans; wrap queries in a span. `reqwest` needs `reqwest-tracing`.
|
|
152
|
+
- **Deno**: `OTEL_DENO=true` covers `fetch`, `Deno.serve` and `node:http`; npm database drivers need their own instrumentation or a hand-written span.
|
|
153
|
+
- **Java, Ruby, .NET, PHP**: the agent, `opentelemetry-instrumentation-all`, the per-library packages (`Npgsql.OpenTelemetry`, `OpenTelemetry.Instrumentation.SqlClient`, ...) and `opentelemetry-auto-pdo` cover JDBC, ActiveRecord, ADO.NET and PDO; confirm the package for the driver in use is present.
|
|
154
|
+
A server span with no client spans under it means this layer was skipped. Before opening the PR, run the app once with the console exporter (`OTEL_TRACES_EXPORTER=console` or the runtime's equivalent) and hit a route that queries the database: a `CLIENT` span carrying `db.system`, even a failed one, proves the driver is patched. List each client and the instrumentation that covers it, or why it is not covered, in the PR description.
|
|
155
|
+
|
|
117
156
|
3. **Logical units of work.** A function that groups several I/O calls into one meaningful step (`checkout`, `syncUser`, `renderInvoice`), or one that is CPU-heavy on its own (parsing a large payload, image resizing, template rendering, serialising a big response). Give each an `INTERNAL` span carrying the identifiers a person debugging it would want (`order.id`, `tenant`, item counts). This turns twelve sibling `SELECT` spans under a handler into a tree that reads like the code and says which step took the time. Rule of thumb: if you would want log lines saying "starting X" and "finished X in N ms", X is a span.
|
|
118
157
|
|
|
119
158
|
Keep spans out of tight loops and trivial helpers. A span per item in a loop of thousands hits the per-replica export limit (see Sampling) and adds nothing a `count` attribute on the parent wouldn't; instrument the loop, not the iteration. Name spans with low-cardinality names (`GET /users/{id}`, `db.query users`, `process order`) and put the variable parts in attributes. Set span status to `ERROR` and record the exception when a unit fails, so `@status:error` finds it. Never put secrets, tokens or raw personal data in span names or attributes.
|
|
@@ -131,7 +170,7 @@ What differs from a repo service:
|
|
|
131
170
|
|
|
132
171
|
Recipe:
|
|
133
172
|
|
|
134
|
-
1. Turn tracing on for the function with `set-service-tracing` (or `railway trace enable --service <function>`) if `get-tracing` shows it off. Leave `autoInstrumentationEnabled` off; it does nothing for Bun.
|
|
173
|
+
1. Turn tracing on for the function in the environment it runs in with `set-service-tracing` (or `railway trace enable --service <function>`) if `get-tracing` shows it off there. Leave `autoInstrumentationEnabled` off; it does nothing for Bun.
|
|
135
174
|
2. Set the exporter variables with `set-variables`. `NodeSDK` exports metrics and logs over OTLP by default and the receiver rejects both. Pass `skipDeploys: true`; the code push in step 5 is the deploy that picks them up. Check `list-variables` first: a function that sets its own `OTEL_EXPORTER_OTLP_ENDPOINT` gets none of Railway's tracing variables.
|
|
136
175
|
|
|
137
176
|
```text
|
|
@@ -147,8 +186,8 @@ Recipe:
|
|
|
147
186
|
import { Hono } from "hono@4";
|
|
148
187
|
import { httpInstrumentationMiddleware } from "@hono/otel@1";
|
|
149
188
|
|
|
150
|
-
// Reads OTEL_EXPORTER_OTLP_
|
|
151
|
-
//
|
|
189
|
+
// Reads OTEL_EXPORTER_OTLP_* and OTEL_SERVICE_NAME from the variables
|
|
190
|
+
// Railway provides. Nothing to configure.
|
|
152
191
|
const sdk = new NodeSDK();
|
|
153
192
|
sdk.start();
|
|
154
193
|
process.on("SIGTERM", () => sdk.shutdown().finally(() => process.exit(0)));
|
|
@@ -175,7 +214,7 @@ Recipe:
|
|
|
175
214
|
export default { port: Number(Bun.env.PORT ?? 3000), fetch: app.fetch };
|
|
176
215
|
```
|
|
177
216
|
|
|
178
|
-
For a function that calls `Bun.serve` itself, wrap its `fetch` handler: take the parent from `propagation.extract(context.active(), req.headers, { get: (h, k) => h.get(k) ?? undefined, keys: (h) => [...h.keys()] })` and run the handler inside `tracer.startActiveSpan(name, { kind: SpanKind.SERVER }, parent, ...)`. For an outgoing call, start a `SpanKind.CLIENT` span and `propagation.inject(context.active(), headers, { set: (h, k, v) => h.set(k, v) })` into a `Headers` object before `fetch`. A cron or script function has no server: its spans are new roots
|
|
217
|
+
For a function that calls `Bun.serve` itself, wrap its `fetch` handler: take the parent from `propagation.extract(context.active(), req.headers, { get: (h, k) => h.get(k) ?? undefined, keys: (h) => [...h.keys()] })` and run the handler inside `tracer.startActiveSpan(name, { kind: SpanKind.SERVER }, parent, ...)`. For an outgoing call, start a `SpanKind.CLIENT` span and `propagation.inject(context.active(), headers, { set: (h, k, v) => h.set(k, v) })` into a `Headers` object before `fetch`. A cron or script function has no server: its spans are new roots, recorded on every run, and it must `await sdk.shutdown()` as its last statement, or the batch never leaves the process. The docs page has all three in full.
|
|
179
218
|
|
|
180
219
|
5. Write it back with `update-function-source-code` (the whole file; pass `staged: true` to stage instead of deploying live) or `railway functions push --path <file>`. This deploy also adds the variables.
|
|
181
220
|
6. Verify with the steps below: `curl -sI https://<domain>/hello/x | grep -i x-railway-trace-id`, then `get-trace` on the ID. A span with `component` `service` and scope `@hono/otel` (or the tracer name) means the function exports. If the deploy logs show `bun install` failing, an import specifier is wrong; if they show OTLP export errors for metrics or logs, step 2 was skipped.
|
|
@@ -184,9 +223,8 @@ Docs: [Functions](https://docs.railway.com/observability/tracing/functions).
|
|
|
184
223
|
|
|
185
224
|
## Sampling
|
|
186
225
|
|
|
187
|
-
- **
|
|
188
|
-
- **A
|
|
189
|
-
- **A client `traceparent` overrides the draw.** A request that arrives with the sampled flag set is always traced; one with it cleared never is. Use this to force a single trace while debugging a service with a low rate:
|
|
226
|
+
- **Every request is traced.** The edge traces 100% of client-facing requests to a traced service and writes the decision into the `traceparent` sampled flag. Railway sets no sampler variables, so the SDK's default parent-based sampler follows the edge and records every root span of its own (cron jobs, queue consumers, private-network calls without a `traceparent`). There is no project or service rate to set.
|
|
227
|
+
- **A client `traceparent` overrides.** A request that arrives with the sampled flag set is always traced; one with it cleared never is. An instrumented client can start a trace that continues into Railway, and a caller can keep a request out of tracing by sending a cleared flag. To trace one specific request while debugging:
|
|
190
228
|
|
|
191
229
|
```bash
|
|
192
230
|
curl -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" https://<domain>/<path>
|
|
@@ -194,7 +232,7 @@ Docs: [Functions](https://docs.railway.com/observability/tracing/functions).
|
|
|
194
232
|
|
|
195
233
|
Generate a fresh random 32-hex trace ID (the second field) for each request; reusing one merges requests into a single trace.
|
|
196
234
|
|
|
197
|
-
-
|
|
235
|
+
- **Sample in the SDK when the volume is too high.** Each replica can export 1,000 spans per 10 seconds; exports over the limit are rejected and the SDK reports a partial success. Disable noisy instrumentations first. If that isn't enough, set `OTEL_TRACES_SAMPLER=traceidratio` and `OTEL_TRACES_SAMPLER_ARG=<fraction>` on the service yourself; a `parentbased_*` sampler follows the edge's flag and would change nothing for edge requests. Traces the SDK drops still show the edge and proxy hops.
|
|
198
236
|
|
|
199
237
|
## Read traces
|
|
200
238
|
|
|
@@ -203,7 +241,8 @@ Traces are read through **Remote MCP** (the default agent path), `railway trace
|
|
|
203
241
|
| Tool | Access | Purpose |
|
|
204
242
|
|---|---|---|
|
|
205
243
|
| `list-traces` | viewer | Traces of an environment, newest first, one row per request with at least one span matching `filter`. Optional `serviceId`, `startDate`/`endDate` (ISO 8601 with timezone; defaults to the last hour), `limit` (default 100, max 500) |
|
|
206
|
-
| `get-trace` | viewer | One trace as an indented span tree, with every span's attributes, events and links in the structured result. Takes `traceId` (32 hex characters); `maxSpans` caps the result and the output says when it was hit |
|
|
244
|
+
| `get-trace` | viewer | One trace as an indented span tree (each line shows the span kind and the attribute that says what it talked to: `db.system`, `http.route`, `url.full` or `server.address`), with every span's attributes, events and links in the structured result. Takes `traceId` (32 hex characters); `maxSpans` caps the result and the output says when it was hit |
|
|
245
|
+
| `get-tracing-coverage` | viewer | What one service's own instrumentation covers: its spans in the window (default the last hour) by span kind, by the remote system they name (`db.system`, `messaging.system`, `rpc.system`, or `http` for HTTP client spans) and by the instrumentation scope that emitted them (`@opentelemetry/instrumentation-pg`, ...). Takes `serviceId`; optional `startDate`/`endDate`. Edge and proxy spans are left out. The one call that answers "are the database queries instrumented?" |
|
|
207
246
|
|
|
208
247
|
Both take `projectId` and an optional `environmentId`; omit it and the `production` environment is used, so pass the ID explicitly when the user is looking at another environment. Traces belong to the environment they were exported from.
|
|
209
248
|
|
|
@@ -240,22 +279,28 @@ Workflow for "why is this request slow / failing":
|
|
|
240
279
|
```
|
|
241
280
|
|
|
242
281
|
2. **Fetch that trace** with `get-trace` or `railway trace get <trace-id>` and the returned ID. Edge and proxy spans confirm tracing is on; a span with `component` `service` confirms the app is exporting. After enabling an SDK, that only happens once the redeploy that added the variables is live; after enabling automatic instrumentation, allow about a minute.
|
|
243
|
-
3. **
|
|
282
|
+
3. **Check what the app covers** with `get-tracing-coverage` for the service, after sending a few requests that hit the database. Every database, cache and queue the service uses must appear under "Remote systems" and the driver instrumentations under "Instrumentation scopes". `SERVER` spans with no database client span mean a driver is still unpatched (see the I/O layer in [What to instrument](#what-to-instrument)); `list-traces` with `@kind:client @db.system:*` is the same check as a trace list.
|
|
283
|
+
4. **Or watch the dashboard.** The Traces tab is at `https://railway.com/project/<project-id>/traces?environmentId=<environment-id>`; its **Trace ID** field accepts a bare 32-hex ID or a whole `traceparent` header. In **Tracing setup**, each service row shows when the edge and the app last exported a span, and the **App** indicator turns green on the first span from the service itself.
|
|
244
284
|
|
|
245
285
|
## Troubleshoot
|
|
246
286
|
|
|
247
|
-
- **No traces at all**: confirm `get-tracing` or `railway trace status` reports tracing on for the service (
|
|
287
|
+
- **No traces at all**: confirm `get-tracing` or `railway trace status` reports tracing on for the service in the environment the user is looking at (the switches and the traces both belong to an environment), the service has a public domain, and the account has Tracing in Priority Boarding. With little traffic, send a request and check for `x-railway-trace-id` on the response, then `get-trace` it.
|
|
288
|
+
- **Traced in `production` but not elsewhere**: tracing is set per environment. Enable it in the other environment with `set-service-tracing` and its `environmentId`, or `railway trace enable --environment <name>`.
|
|
248
289
|
- **Edge spans only, nothing from the app** (`get-trace` shows only `edge` and `proxy` components): the variables land on the next deploy, so redeploy. Then check the service doesn't set its own `OTEL_EXPORTER_OTLP_ENDPOINT`, the SDK loads before the app serves, and, for OBI, the process is a supported runtime handling HTTP or gRPC.
|
|
290
|
+
- **Server spans but no database or client spans** (`get-tracing-coverage` shows `SERVER` and `INTERNAL` only, or `get-trace` shows a request span with no `CLIENT` children): the driver is not instrumented. In Node.js an ES-module app without the `@opentelemetry/instrumentation/hook.mjs` loader, Prisma without `@prisma/instrumentation`, or a client no instrumentation covers (postgres.js, Drizzle on it, `Bun.sql`); in Python a missing `opentelemetry-bootstrap -a install`; in Go an unwrapped `database/sql`. See the I/O layer in [What to instrument](#what-to-instrument).
|
|
249
291
|
- **App spans appear as separate traces** (`list-traces` shows service-rooted traces with `hasEdge` false next to edge-only ones): the SDK isn't reading `traceparent`. Enable the W3C Trace Context propagator and make sure nothing in front of the handlers strips the header.
|
|
250
292
|
- **SDK logs metrics or logs export errors**: set `OTEL_METRICS_EXPORTER=none` and `OTEL_LOGS_EXPORTER=none`.
|
|
251
293
|
- **Duplicate spans per request**: the service runs an SDK with automatic instrumentation on. Switch it off with `set-service-tracing` (`autoInstrumentationEnabled` false), or on the CLI `railway trace disable --auto-instrument` then `railway trace enable`.
|
|
252
|
-
- **Spans missing from a busy service**: over 1,000 spans per replica per 10 seconds. Disable noisy instrumentations or
|
|
294
|
+
- **Spans missing from a busy service**: over 1,000 spans per replica per 10 seconds. Disable noisy instrumentations or sample in the SDK; see [Sampling](#sampling).
|
|
253
295
|
- **A Function shows edge spans only**: automatic instrumentation can't help (Bun); the SDK has to be in the file. Check `get-function-source-code` for the `NodeSDK` block and the request wrapper, that the deploy logs show `bun install` succeeding, and that `OTEL_METRICS_EXPORTER`/`OTEL_LOGS_EXPORTER` are `none`. See [Instrument a Function (Bun)](#instrument-a-function-bun).
|
|
254
|
-
-
|
|
296
|
+
- **`railway config plan` wants to remove `tracing`**: the IaC SDKs drop the field, so every plan against a traced service proposes turning it off. Don't apply it; see [Infrastructure as code](#infrastructure-as-code).
|
|
255
297
|
|
|
256
298
|
## Validated against
|
|
257
299
|
|
|
258
|
-
- Docs: [tracing.md](https://docs.railway.com/observability/tracing), [automatic-instrumentation.md](https://docs.railway.com/observability/tracing/automatic-instrumentation), [nodejs.md](https://docs.railway.com/observability/tracing/nodejs), [tracing/functions.md](https://docs.railway.com/observability/tracing/functions), [functions.md](https://docs.railway.com/functions), [variables/reference.md](https://docs.railway.com/variables/reference)
|
|
259
|
-
-
|
|
260
|
-
-
|
|
300
|
+
- Docs: [tracing.md](https://docs.railway.com/observability/tracing), [automatic-instrumentation.md](https://docs.railway.com/observability/tracing/automatic-instrumentation), [nodejs.md](https://docs.railway.com/observability/tracing/nodejs), [tracing/functions.md](https://docs.railway.com/observability/tracing/functions), [functions.md](https://docs.railway.com/functions), [variables/reference.md](https://docs.railway.com/variables/reference), [cli/trace.md](https://docs.railway.com/cli/trace), [infrastructure-as-code/reference.md](https://docs.railway.com/infrastructure-as-code/reference)
|
|
301
|
+
- Public GraphQL API (`railway api schema`): `ServiceInstance.tracingEnabled`, `ServiceInstance.autoInstrumentationEnabled` and `ServiceInstanceUpdateInput` as the per-environment path; `Project.tracingEnabled`, `Project.tracingSampleRate`, `Service.tracingEnabled`, `Service.autoInstrumentationEnabled` and their update inputs marked deprecated; the `traces`, `trace` and `tracingStatus` queries
|
|
302
|
+
- Railway MCP (`https://mcp.railway.com`) tool descriptions and schemas: `get-tracing` and `set-service-tracing` with `environmentId`, `describe-service`, `list-traces`, `get-trace`, `get-tracing-coverage`, `get-function-source-code`, `update-function-source-code`
|
|
303
|
+
- CLI source (railwayapp/cli, per-environment `railway trace` and the IaC `tracing` block in #1239): `src/commands/trace.rs` (subcommands, `--all`, `--environment`), `src/iac/compiler.rs` (`services[id].tracing` on service nodes), `src/iac/change_set.rs` (tracing diff, `deployEffect`, removal when the block is absent), `src/commands/config/mod.rs` (pull renderer)
|
|
304
|
+
- Provided variables observed on a traced service's deploy: the five `OTEL_*` variables in the table above and no sampler variables
|
|
305
|
+
- Function runtime: the public `ghcr.io/railwayapp/function-bun:1.4.0` image (Bun 1.4.0, bare imports turned into a `package.json` and installed with `bun install` at every start)
|
|
261
306
|
- Function examples run on Bun 1.4.0 with `@opentelemetry/sdk-node` 0.222.0 and `@hono/otel` 1.1.2 against a stub OTLP receiver: server span continues the incoming `traceparent`, client span propagates it, script flushes on `sdk.shutdown()`
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# AGENTS.md — your build agent (read this first)
|
|
2
2
|
|
|
3
|
-
> **Single source of truth** for Claude Code, Cursor, and Codex
|
|
4
|
-
>
|
|
3
|
+
> **Single source of truth** for Claude Code, Cursor, and Codex. Claude Code and Codex read this
|
|
4
|
+
> file directly; `.cursor/rules` points here. You are talking to a non-technical vibe coder.
|
|
5
|
+
|
|
6
|
+
Use the plain words in @language.md whenever you talk to the vibe coder.
|
|
5
7
|
|
|
6
8
|
<!-- vybekiit:generated:start contract -->
|
|
7
9
|
## The contract: Decide + Guide
|
|
@@ -19,7 +21,9 @@ A request such as "Can people book my classes?" means build the working feature.
|
|
|
19
21
|
|
|
20
22
|
## How to work
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
A greeting, a plain "help", or "what is this" in a project whose `checklist.md` Decision log has
|
|
25
|
+
no dated entries starts the onboarding skill (`.vybekiit/skills/onboarding.md`). Other simple
|
|
26
|
+
questions need brief answers, without setup or skill searches. Inspect before making
|
|
23
27
|
project-specific claims. Requests for work mean do the work and verify the requested behavior.
|
|
24
28
|
Reuse instructions already loaded in the conversation. Continue authorized work independently;
|
|
25
29
|
one action at a time limits steps the buyer must take. Prefer this project's skills over global
|
|
@@ -39,4 +43,8 @@ copies. Do not use helper agents for simple exchanges.
|
|
|
39
43
|
- MVC layout: `src/routes/`, `src/controllers/`, `src/middleware/`, `src/services/`.
|
|
40
44
|
- Use `@vybekiit/*` packages — never reinvent auth, db, or payments.
|
|
41
45
|
- Secret settings live in `.env` only — never read values aloud in chat.
|
|
46
|
+
- Settings that are not secret (which services the app uses, public ids, web addresses, ports)
|
|
47
|
+
live in `settings.env`, saved with the code. A key listed there is set there; secrets and
|
|
48
|
+
private values stay in `.env`. Never put a secret in `settings.env`. A value the host already
|
|
49
|
+
sets wins over both files.
|
|
42
50
|
- Session cookies are httpOnly; mobile/extension clients use `APP_URL` pointing here.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| The builder says something like… | Use this skill |
|
|
4
4
|
|---|---|
|
|
5
|
-
| "set up my server", "let's start" | `skills/onboarding.md` |
|
|
5
|
+
| "hi", "help", "what is this", "set up my server", "let's start" | `skills/onboarding.md` |
|
|
6
6
|
| "let people sign in" | `skills/wire-auth.md` |
|
|
7
7
|
| "save my data", "add a database" | `skills/wire-database.md` |
|
|
8
8
|
| "add payments" | `skills/wire-payments.md` |
|