IaC buckets:
region
is effectively required, undocumented, and fails silently when wrong
mattijsdp
PROOP

3 months ago

CLI 5.20.0 · railway (railway-ts-sdk) 3.3.2 · Node 24

The IaC reference lists bucket region as optional. In practice it's required, and getting it wrong fails in a silent, confusing way:

  1. A region-less bucket silently breaks the whole apply. bucket("store") with no region never provisions ("Bucket region undefined is invalid" in the dashboard), and because it's in the same config apply as a service(), the service is left stranded at serviceInstances = 0 too. Yet config apply prints ✓ Create bucket / ✓ Create service and exits 0 — the environmentApplyChangeSet mutation returns status: "applied" with empty diagnostics. Nothing tells you anything went wrong; you just find non-functional resources later.

  2. The valid region values are undiscoverable. The docs show exactly one (iad, in an example) and don't list the set. The API doesn't expose it either — no region enum, and region isn't a field on BucketCreateInput / Bucket / BucketInstanceDetails. The regions query lists deployment regions (us-east4-eqdc4a → "Virginia", …) — which is the obvious thing to try, but buckets reject those. Bucket regions are the Tigris/airport-style codes (iad), which isn't stated anywhere. I wasted time setting region: "us-east4-eqdc4a" and getting the same silent failure as no region. Worse: a working bucket's own S3 credentials report region: "auto", but passing region: "auto" back in is also rejected (same silent strand) — so the value you read out isn't a value you can put in.

Repro

package.json: { "private": true, "type": "module", "devDependencies": { "railway": "3.3.2" } }

.railway/railway.ts:

import { defineRailway, project, service, bucket, image } from "railway/iac";

export default defineRailway(() => {
  const store = bucket("store");                       // no region  -> silent failure
  // const store = bucket("store", { region: "iad" }); // valid region -> both deploy
  const web = service("web", { source: image("nginx:latest"), env: { FOO: "bar" } });
  return project("iac-bucket-repro", { resources: [store, web] });
});
npm install && railway init --name iac-bucket-repro && railway config apply --yes

Verified via GraphQL:

no region : bucketS3Credentials -> "BucketInstance not found"   |  web serviceInstances = 0
region iad: bucketS3Credentials -> { endpoint: "…storageapi.dev", … }  |  web serviceInstances = 1, SUCCESS
$20 Bounty

2 Replies

Railway
BOT

3 months ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway • 3 months ago


Status changed to Awaiting Railway Response Railway • 3 months ago


mattijsdp
PROOP

3 months ago

A bucket’s region has no typed GraphQL input — BucketCreateInput/Bucket/BucketUpdateInput have no region field; the only region in the API is the output S3-cred value auto. Region travels only inside the untyped environmentApplyChangeSet(input: JSON!) blob, so a missing/invalid value is accepted and the mutation returns status:"applied" → silent failure. The SDK does ship a closed union BucketRegion = "sjc"|"iad"|"ams"|"sin", but it’s optional and the IaC runner evaluates railway.ts via tsx, which transpiles without type-checking — so the union enforces nothing at apply time, and diffGraphs() validates a region change but never a region on create.

The fixes/improvements that I think are required:

  1. Validate every desired bucket’s region in diffGraphs(). A missing/invalid region pushes a severity:"error" diagnostic → planned.ok=false → applyRailwayIac() returns before calling applyChangeSet. So apply aborts with a clear error and no backend change is needed. Then you can get errors like:
  • Bucket assets is missing a region. Set one of: sjc, iad, ams, sin.
  • Bucket assets has an invalid region "us-east4-eqdc4a". Valid object-storage regions are sjc, iad, ams, sin.
  1. Make region required + documented (docs). The IaC reference only shows iad and never lists the set — the valid codes only live on docs.railway.com/cli/bucket. Add to the reference: region is required, plus the table — sjc (US West), iad (US East), ams (EU/Amsterdam), sin (Singapore) — and a note that these are not the deployment region codes (us-east4-eqdc4a etc.) and that auto can’t be passed back.

  2. Backend: environmentApplyChangeSet should reject a bucket with missing/invalid region with a diagnostic instead of returning applied — and fix the collateral bug where a bad bucket-create in the same change set strands co-created services at serviceInstances=0.


Anonymous
FREE

21 days ago

I checked the native CLI 5.57.1 planner and reproduced the missing validation. A new bucket with a missing region, auto, or a deployment-region code could enter the change set without an error.

I opened a focused fix: https://github.com/railwayapp/cli/pull/1206

The proposed guard validates new buckets against the existing object-storage codes (sjc, iad, ams, sin) and reports errors at resources.bucket.<name>.config.region. The native runner's existing error handling then stops preview/apply for the whole newly evaluated plan, including a co-created service.

The complete CLI test binary compiled on Ubuntu and all 76 IaC tests passed at the exact PR head. Six bucket tests cover missing/null fields, invalid strings and JSON types, all valid regions, a co-created service, and existing-region handling. Three of those tests fail against the unpatched planner. CI: https://github.com/mrfandu1/cli/actions/runs/34918114153

The fix is awaiting maintainer review. For now, set an explicit bucket region before applying. Backend validation, previously saved plans, and repair of already-stranded resources remain separate work. No Railway resources were changed for these tests.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...