{"record":{"id":"39429c302aab950e","repo":"Budibase/budibase","slug":"deployment-failed-message","errorCode":null,"errorMessage":"Deployment Failed: ${message}","messagePattern":"Deployment Failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/api/controllers/deploy/index.ts","lineNumber":558,"sourceCode":"        await initDeployedApp(prodId)\n\n        return { app: appDoc, prodWorkspaceId: prodId }\n      } finally {\n        if (replication) {\n          await replication.close()\n        }\n      }\n    })\n  } catch (error: unknown) {\n    const message =\n      error instanceof Error\n        ? error.message\n        : typeof error === \"string\"\n          ? error\n          : \"Unknown error\"\n    deployment.setStatus(DeploymentStatus.FAILURE, message)\n    await storeDeploymentHistory(deployment)\n    throw new Error(`Deployment Failed: ${message}`, { cause: error })\n  }\n\n  try {\n    await syncStaticFormulasToProduction(migrationResult.prodWorkspaceId)\n  } catch (error: unknown) {\n    const message =\n      error instanceof Error\n        ? error.message\n        : typeof error === \"string\"\n          ? error\n          : \"Unknown error\"\n    deployment.setStatus(DeploymentStatus.FAILURE, message)\n    await storeDeploymentHistory(deployment)\n    throw new Error(`Deployment Failed: ${message}`, { cause: error })\n  }\n\n  deployment.setStatus(DeploymentStatus.SUCCESS)\n  await storeDeploymentHistory(deployment)","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/deploy/index.ts#L540-L576","documentation":"Generic deployment failure wrapper in publishWorkspaceInternal. Any error thrown by syncStaticFormulasToProduction is caught, the deployment is marked FAILURE with the underlying message, history is stored, and a new Error(\"Deployment Failed: <message>\") is thrown with the original as cause. It standardizes publish failures surfaced to the caller.","triggerScenarios":"The second catch block in publishWorkspaceInternal fires when syncStaticFormulasToProduction(prodWorkspaceId) rejects — DB write failures on the prod workspace, missing prod DB, or formula sync exceptions.","commonSituations":"Prod workspace DB unavailable or locked; static formula definitions malformed after migration; CouchDB write conflicts; resource limits hit during a large publish.","solutions":["Inspect error.cause / deployment history to see the underlying sync failure","Verify the prod workspace DB exists and CouchDB is healthy","Re-run the publish; static formula sync can be retried","Check static formula definitions in the app for malformed entries","Scale/verify CouchDB resources if writes are timing out on large apps"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"await api.get(`/health`) // confirm server & CouchDB reachable before publishing\nconst apps = await api.get(\"/api/applications\")\nif (!apps.some(a => a.appId === appId)) throw new Error(\"app missing\")\n","typeGuard":null,"tryCatchPattern":"try {\n  await api.post(`/api/applications/${appId}/publish`)\n} catch (err) {\n  if (err.message.startsWith(\"Deployment Failed\")) {\n    const cause = err.cause?.message ?? err.message\n    console.error(\"Publish failed at:\", cause)\n    // inspect deployment history, fix root cause, retry\n  } else { throw err }\n}\n","preventionTips":["Check CouchDB health and disk space before large publishes","Review deployment history docs after any failure for the root cause","Keep static formula definitions valid and tested","Ensure prod workspace DB exists and is replicated"],"tags":["publish","deployment","static-formulas"],"backgroundTag":"deployment-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}