From 7944db8ba4c4f2e788b953b3154c9511767861d1 Mon Sep 17 00:00:00 2001 From: Mark Henderson Date: Thu, 23 Apr 2026 17:27:31 -0700 Subject: [PATCH] fix(coolify): upsertServiceEnv falls back to PATCH on already-exists Coolify auto-creates env entries (with empty values) for every ${VAR} reference it finds in the compose YAML at service-creation time. So POST /services/{uuid}/envs returns 'already exists' for any env we try to set after creation. The fix is to fall back to PATCH on that specific error, making the helper a true upsert. Made-with: Cursor --- lib/coolify.ts | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/coolify.ts b/lib/coolify.ts index c95efce..42671c0 100644 --- a/lib/coolify.ts +++ b/lib/coolify.ts @@ -576,10 +576,26 @@ export async function upsertServiceEnv( uuid: string, env: ServiceEnvVar, ): Promise { - await coolifyFetch(`/services/${uuid}/envs`, { - method: 'POST', - body: JSON.stringify(env), - }); + // Coolify auto-creates env entries (with empty values) for every + // ${VAR} reference in the compose file at service-creation time. + // POST to /envs returns "already exists" for those — we must use + // PATCH to update them. Try POST first, fall back to PATCH. + try { + await coolifyFetch(`/services/${uuid}/envs`, { + method: 'POST', + body: JSON.stringify(env), + }); + } catch (err: unknown) { + const msg = err instanceof Error ? err.message : String(err); + if (msg.includes('already exists')) { + await coolifyFetch(`/services/${uuid}/envs`, { + method: 'PATCH', + body: JSON.stringify(env), + }); + return; + } + throw err; + } } export async function listAllServices(): Promise>> {