First apply against a fresh project 404s — cast never creates the Coolify environment #38
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#38
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happens
The first
cast applyagainst a project that does not yet exist creates the project, then fails on the first resource create:The project is left created and empty. Every subsequent create in the same run would fail the same way.
Root cause
ensureProjectcreates the project with the name only (src/cli.ts:1679):Coolify gives a newly created project its own default environment, named
production. cast then sends every resource create withenvironment_name: coolifyEnv(src/cli.ts:1819,:1841,:1866), where:With
--env prodand no--environment, that isprod— an environment which does not exist on the fresh project. Hence the 404.Two comments in the source assert the missing behaviour as though it were implemented:
src/cli.ts:716— "since apply creates the environment from this value"src/cli.ts:808— "The name the environment gets ON COOLIFY when apply creates it"cast never creates an environment. There is no call to the route that would do it, and that route does exist in the vendored 4.1.2 spec (
reference/coolify-openapi-4.1.2.json):Why it has gone unnoticed
Every environment cast has touched so far was created by hand in a UI and then adopted — so the environment always already existed, under whatever name someone typed (which is exactly why
--environmentwas added). The genuinely-from-nothing first apply is the one path that had never been exercised.Suggested fix
In
ensureProject(or immediately after it), reconcile the environment before any resource create:GET /projects/{uuid}(or/projects/{uuid}/environments) → list existing environment names.coolifyEnvis absent,POST /projects/{uuid}/environments { name: coolifyEnv }.Idempotent, so it is safe on every apply, not just the first — and it makes the two comments above true.
Worth deciding alongside: a brand-new project is now left carrying an empty
productionenvironment beside ours. That is precisely the shape that makes an adopted box confusing to read later (an emptyproductionsitting next to the environment everything actually lives in). Options are to leave it, or to delete it when cast created the project itself and the default is empty —DELETE /projects/{uuid}/environments/{name}exists.Workaround
Create the environment by hand once, then re-run apply unchanged:
Passing
--environment productionalso gets past it, but adopts Coolify's default name permanently and means carrying the flag on every subsequent verb for that environment — the trade-off--environmentexplicitly exists to avoid making by accident.