lavela MCP tools

The details behind the lavela MCP tool descriptions — each description links to one section here. What lavela does, and every tool with its cost, is on /info (for agents: /llms.txt). Prices: /pricing.

Connect

Add the server to any MCP client that supports remote servers with browser sign-in (OAuth) — nothing to paste:

https://console.lavela.dev/api/mcp

That URL gives the core tools — the "deploy this repo → operate it" journey: lavela.account_status, lavela.analyze_stack, lavela.launch_saas, lavela.list_projects, lavela.project_overview, lavela.connect_github, lavela.deploy_link, lavela.provision_compute_from_repo, lavela.compute_build_status, lavela.compute_rebuild, lavela.provision_hosting, lavela.get_status, lavela.redeploy, lavela.get_logs, lavela.check_health, lavela.set_compute_secret, lavela.set_build_vars, lavela.env_link, lavela.compute_lifecycle, lavela.compute_always_on, lavela.destroy_compute, lavela.provision_database, lavela.list_resources, lavela.provision_domain, lavela.diagnose_domain, lavela.provision_email, lavela.connect_stripe, lavela.create_checkout, lavela.topup_link, lavela.resume_compute, lavela.delete_project.

For every tool — ads, schedules (cron), preview environments, security scans, legal documents, volumes / object storage, one-off jobs and exec, pushing a private image, and the rest listed under Advanced tools — connect with:

https://console.lavela.dev/api/mcp/all

Sign-in is the same for both URLs (each is its own OAuth protected resource). To switch an existing connection, remove the lavela connector and add it again with the other URL. Claude Code keeps a connection in up to three places (user, local and project), and a leftover one — an old address, or an Authorization header from an old token — stops the browser sign-in from starting, so remove it from all three first (a line for a place with no entry only says so), then add it with the URL you want:

claude mcp remove lavela -s user
claude mcp remove lavela -s local
claude mcp remove lavela -s project
claude mcp add --transport http --scope user lavela https://console.lavela.dev/api/mcp

For every tool, end with this line instead:

claude mcp add --transport http --scope user lavela https://console.lavela.dev/api/mcp/all

npx @lavela/cli connect sets up Claude Code, Cursor, Windsurf and Claude Desktop with the core URL. A static token (Authorization: Bearer mcp_…), created in the console under Settings → Connect your agent → Manage connections → When you need a manual token, works on either URL.

What a connection can do. A browser sign-in, and npx @lavela/cli connect, give the connection every permission except adding funds (projects, provisioning, ops such as ads and security scans, and reading the balance); a manual token has only the permissions the user chose when creating it. lavela handles a request made within those permissions as the user's own request. The user can disconnect an app or revoke a token at any time under Settings → Connect your agent → Manage connections: a revoked token stops working at once, and a disconnected app's current access ends within about an hour.

When a core connection's result names a tool it doesn't have, its next_step.reason starts with "Advanced tool — not in this connection…" — ask the user to reconnect with https://console.lavela.dev/api/mcp/all. Start every new conversation with lavela.account_status. A connected client also lists a guided prompt, launch-my-app ("Launch my app"; in Claude Code type /mcp__lavela__launch-my-app, with the repo URL if known), that walks the first launch step by step.

Deploy from repo

lavela runs an app one of two ways. lavela.analyze_stack says which lane fits the app (its lavela field), and lavela.launch_saas — which creates the project — decides for this account in its deploy field and next_step:

LaneToolFor
A server built from the repolavela.provision_compute_from_repoAn app with its own server (Node, Python, Go, Java, Ruby, Rust, PHP, multi-service), and every app while the account is on the free welcome credit
Web hostinglavela.provision_hostingA web frontend (static, Vite, Next.js, Astro, SvelteKit, Remix) on a funded account

A server is paid from the lavela wallet — confirm with the user before starting one (Money). Web hosting needs a funded account (not the welcome credit) but isn't charged to the wallet while it runs. launch_saas is not idempotent: a retry creates a second project, so check lavela.list_projects first.

Building a server from a repo. lavela builds on its own servers from GitHub — the repo's Dockerfile when it has one, otherwise an auto-detected build; the user needs no Docker. The call returns a buildId; builds usually take 3–6 minutes. Poll lavela.compute_build_status (each call waits up to ~20 seconds) until ok or failed and don't start another build meanwhile. Anything not passed gets the default: the repo root, the default branch, port 8080, no env — and a new server is 512 MB. On a redeploy, leaving size (or alwaysOn) out keeps what the running server has; passing it sets it (512mb shrinks a bigger server to 512 MB). Use gitRef for a branch/tag/commit and subdir for a folder of a monorepo. Multi-service: call once per service with a distinct service (web, api, worker) — e.g. the same repo with env {"SERVICE":"api"}.

Reading the repo first. lavela.analyze_stack also says, when it finds them: diskData — signs of a SQLite or file-based database, or of uploads kept on the server's own disk, which is wiped on every redeploy, restart and sleep (ask the user whether that data belongs in a database or on a volume before deploying); and readWarning — the repo could not be read (a wrong URL, or a private repo: connect_github), which is never answered as a static site. An app whose only database is its own Supabase project shows deploy.db: "none" and databaseConnection.migrationRequired: false: lavela keeps that project and creates no database for it, so there is nothing to migrate.

Server sizes. Every account can run the default size, 512 MB (512mb) — the only size on the free welcome credit. After the account's first paid top-up (and once the user has accepted the current Terms, which list the sizes), a bigger size, up to 8 GB (1gb, 2gb, 4gb, 8gb), can be chosen: on a deploy with the size parameter of lavela.provision_compute_from_repo, or in place for a running server with lavela.compute_set_size (an advanced tool — connect with https://console.lavela.dev/api/mcp/all; the server restarts once, no rebuild). A smaller size needs no top-up; before the user accepts the current Terms, only a change back to 512 MB is allowed (CONSENT_REQUIRED otherwise). A bigger size costs more while awake or always on: confirm the price with the user first, quoting a server that sleeps when idle as a range — its asleep price up to its always-on price, the most it can cost a month (Money). A running server's prices are in lavela.project_overview (asleepMonthlyUsd, capMonthlyUsd, with monthToDateUsd and awakeShare for this month so far), every size's on /pricing (and lavela.compute_estimate {size}, advanced — its monthlyUsd is the most the server can cost a month). Before that top-up a bigger size is refused — SIZE_NEEDS_PAID_TOPUP (TRIAL_ROUTE_UNSUPPORTED on the welcome credit): the user adds funds once, then call again. An account that got the welcome credit and whose paid top-ups were all refunded is back on the credit's rules: no bigger size and no growing a server until its next paid top-up (a server already running at a bigger size keeps running; redeploying it then meets the credit's limits). Redeploys and lavela.compute_rebuild keep a server's size; lavela.compute_set_size is the way to change only the size.

Private repos: lavela.connect_github gives a link the user opens once. Code that isn't on GitHub: for a project that already exists, an account with a paid top-up can use lavela.deploy_link — a one-time link (30 minutes, one per service) where the user connects GitHub or drags in the folder; the first call may answer CONSENT_REQUIRED — the user accepts the Terms at the link it gives, then call again. An account with only the welcome credit can't upload a folder (TRIAL_ROUTE_UNSUPPORTED, and a folder dragged in on that page is refused after it is packed): help the user put the code on GitHub first (they can create a repository there), then deploy that repo.

Ports. lavela sets PORT to the port it routes HTTPS to (default 8080). An app that reads $PORT needs nothing. An app that binds a fixed other port needs internalPort — setting only env: { PORT: … } changes the app but not the routing, and every request answers 502.

Environment variables and .env files. An app's variables are of two kinds, set in two places — and the agent never reads a .env value:

For the user's whole .env, call lavela.env_link {projectId}: it returns the way that works for this account to send it, with public entries stored as build settings and the rest as secrets — a command for the user to run in the project folder, npx @lavela/cli env push --project <id> (it prints variable names only and the user clicks Allow once in their browser; --dry-run shows the sorting without sending anything), or else a console page where they paste the file. Values travel from the user's computer or browser straight to lavela, never through the agent or the chat. If env_link has no route for the account yet, or for a single secret, set_compute_secret takes a value directly — it then passes through the conversation, so confirm with the user first. A deploy's own env is for non-secret runtime settings.

The disk is not permanent — see Persistent data.

Web hosting details. provision_hosting builds the frontend and adds a database when the app needs one. Build-time env (e.g. NEXT_PUBLIC_SUPABASE_URL + anon key) is stored encrypted on the project and reused by later redeploys — pass only what changes; it may be bundled into the browser, so never put server secrets there. subdir and branch are remembered ("" goes back to the repo root / default branch); a branch name containing "/" must be passed as branch, not as a /tree/… URL. Up to 600 files / 8 MB of build files are sent; optional files (images in public/, docs, tests) may be left out (filesTruncated: true), and a repo whose build files alone are bigger is refused with REPO_TOO_LARGE_FOR_HOSTING — deploy it as a server instead. Other failures:

ErrorWhat to do
APP_NEEDS_SERVERThe app runs its own server — deploy it with provision_compute_from_repo
DB_ENV_MISSINGA Supabase app with no URL / anon key anywhere lavela can see — ask the user (Supabase → Project Settings → API) and pass them as env
SUBDIR_EMPTYThe folder had no files — pass the right subdir ("" = the repo root)
GITHUB_TREE_UNAVAILABLElavela couldn't read the repo — a private repo needs connect_github; a public one may be rate-limited, redeploy in a few minutes
HOSTING_DB_QUOTAThe account has no lavela database left for the app (or lavela isn't creating any right now). The error says what it counted: N/M hosted apps with a lavela database counts only the databases made for web apps; N of its M lavela Postgres databases counts all of the account's — web apps', provision_database ones and ones left by deleted projects, which it names with their ids (account_status lists those too). Free one that was counted (list_resources → destroy_resource, with the user's agreement: its data is lost), or redeploy with the user's own DATABASE_URL in env (the console deploy form takes it too)
MANAGED_POOL_FULLlavela's database capacity is full right now — redeploy with the user's own DATABASE_URL in env, or try later

"200 ≠ live." A finished hosting deploy can still serve an error or blank page: get_status shows the hosting module's verified: false with a verifyWarning. Before telling the user the app is live, open the URL or call lavela.check_health (it checks for a real page, not just any HTTP 200).

Nothing watches a server for you. Servers are not monitored, and no alert is sent if one goes down — don't promise the user one. A web-hosting site is checked every 15 minutes, and a change (down, back up) is sent to the project's Slack, Discord or JSON webhook channels (Operations → Notifications), never by email. For a server, call lavela.check_health when the user asks whether the app is up (it wakes a sleeping server, billed as awake time) and read lavela.get_logs.

Build status codes

lavela.compute_build_status returns building, ok (with the live URL) or failed. Its next_step always carries the fix; this table is the reference.

The build ran and failed:

CodeMeaningFix
CONNECT_GITHUBlavela couldn't clone the repo (usually private)connect_github, then build again
SOURCE_FETCH_FAILEDThe code couldn't be fetched — wrong repo URL, branch or folder, or an expired uploadCheck them with the user; uploaded code → a new deploy_link
BUILD_PLAN_FAILEDlavela couldn't tell how to start the app. When it could tell why, the error says so and ends in a tag: [cause: monorepo_root] (the repo root is a monorepo — package.json workspaces or pnpm-workspace.yaml — with nothing to start; [folders: …] lists the apps) or [cause: python_no_start] (a Python app with no Procfile; the error gives the exact line)Add a start command (a start script in package.json; for Python a Procfile line such as web: uvicorn main:app --host 0.0.0.0 --port $PORT or web: gunicorn app:app --bind 0.0.0.0:$PORT, listening on 0.0.0.0 and the port in $PORT) or a Dockerfile, push, then build again. A monorepo root: deploy one app's folder (provision_compute_from_repo with subdir)
APP_BUILD_FAILED, BUILD_FAILEDThe app's own install/compile step failed. Tags: [cause: node_version] (the app needs a newer Node.js than the build used) or [cause: go_toolchain] (go.mod names a Go version the build could not download)Read get_logs, fix the code (with the user's OK), push, build again. Node: set engines.node in package.json or a .nvmrc; Go: write the three-part release number in go.mod (go 1.25.0)
BUILD_TIMEOUTThe build ran past its time limit — 30 minutes, or 10 while the account has only the welcome credit (the error says which) — a huge install or a step that never ends (a dev/watch server, a prompt)Read get_logs; building it unchanged stops at the same place. On the welcome credit a paid top-up of any amount raises the limit to 30 minutes
BUILD_STALLED, PLATFORM_ERRORStopped on lavela's side, not the codecompute_rebuild (same settings); if it fails the same way twice, contact support
BUILD_REGISTRY_UNAVAILABLElavela's image registry was unavailable — lavela's side, nothing charged. counted and its error say whether the build counts toward the build limits: false — "did not start … does not count" (refused before its builder started) — or true — "still counts" (its push failed after it started)Wait a few minutes, then compute_rebuild (same settings); no build log, nothing in the code to fix
BUILDER_OUT_OF_RESOURCESlavela's own build machine ran out of disk space or memory while building — lavela's side, not the app's code, and nothing was charged (builds are included). counted and its error say whether the build counts toward the build limits: false — "does not count" (an account's first few such failures in a day) — or true — "still counts" (past that allowance). The build log has nothing to fixcompute_rebuild (same settings), once; if it stops the same way again, contact support. Don't change the code for it
SPEND_CAP with counted: trueThe account was capped or suspended while the build ran, so its image push was refused. The builder ran: it counts toward the build limits; nothing in the code to fixaccount_status says what lifts it, then compute_rebuild
BUILD_CANCELLEDThe project was deleted (or is no longer the account's) while the build ran, so its image push was refused — the owner's own act; nothing deployed, nothing in the code to fix; it counts toward the build limitsNothing to retry; set the project up again if it is still wanted
CREDENTIAL_IN_MACHINE_CONFIGlavela refused to start the builder because its own settings held an infrastructure token — lavela's side, nothing built or chargedWait a few minutes, then compute_rebuild; if it fails the same way twice, contact support
NETWORK_UNVERIFIED, NETWORK_MISMATCH, APP_NAME_UNAVAILABLE, NETWORK_CAPACITY_REACHED, SERVICE_OPERATION_STALEThe service registry refused to start the build's server (its network could not be proven or is not the project's own, its name is taken, lavela's network capacity is full, or another change replaced the build's step) — lavela's side, nothing built or chargedWait a few minutes, then compute_rebuild; if it fails the same way twice, contact support

The build was refused before it started — the builder never ran, so there is no build log and nothing in the code to fix; the fix is the account's (for SIZE_NOT_OFFERED, the request's):

CodeMeaningFix
TRIAL_SERVER_LIMIT_REACHEDThe free trial runs one server at a timeRemove the one no longer needed (project_overview → destroy_compute, or delete_project), or add funds — any top-up lifts every trial limit
TRIAL_ROUTE_UNSUPPORTEDNot part of the trial (a bigger size, resizing a running server, uploaded code, web hosting, …)The small size / a GitHub repo, or add funds — and for a closed lane, its way around under When a lane is closed on the welcome credit (Money)
INSUFFICIENT_WALLET_BALANCE, INSUFFICIENT_AVAILABLE_BALANCEThe balance can't cover a servertopup_link, then build again
NO_CARDAn older-plan account with no payment methodaccount_status first (a claimable welcome credit), else billing_setup_card
SPEND_CAP, CAPPEDCompute is capped or pausedaccount_status says why and what lifts it
PAYMENT_EXHAUSTEDA card payment failed (older plan)The user updates the card
MACHINE_LIMITThe project already runs its maximum number of serversRemove one
SIZE_NEEDS_PAID_TOPUPA size above 512 MB (for a new server, or growing one) on an account without a paid top-up — never made one, or back on the welcome credit after they were all refundedTell the user the size's monthly price (the message has it); one paid top-up of any amount (topup_link), then call again — or use 512mb
SIZE_NOT_ON_PLANA size above 512 MB (for a new server, or growing one) on an account on the older card plan (not on the prepaid balance)Don't offer a top-up — the user contacts support@lavela.dev to move plans; meanwhile use 512mb, keep the server's current size, or go smaller
SIZE_NOT_OFFEREDNot one of lavela's sizes (e.g. cpuKind / cpus / memoryMb that match none)Call again with size: 512mb, 1gb, 2gb, 4gb, 8gb — or leave it out (a new server is 512 MB, a running one keeps its size)
MEMORY_CEILING, CPU_CEILING, PERFORMANCE_NOT_ALLOWEDThe size is above the account's limitDeploy again at an allowed size, keeping the other settings
RATE_LIMITToo many servers started in the last hourWait, then build again
WALLET_COMPUTE_DISABLEDlavela paused new servers platform-wideTry later; support if it persists
ORG_CAPACITY_REACHEDlavela's servers are at capacity (nothing was started or charged; lavela has been alerted)Tell the user — nothing in the request or the account changes it; don't retry in a loop
TRIAL_CAPACITY_FULLFree trial servers are full; they free up only when trial servers are removed (nothing was charged)Add funds to deploy now (the welcome credit stays): topup_link, then build again
ACCOUNT_MACHINE_LIMITThe account is at its machine limit (servers, jobs, running builds; stopped servers count)Remove servers no longer needed, or contact support
REGISTRY_UNAVAILABLElavela's image registry is switched off right now — lavela's side; nothing was queued, built, charged or counted (push_image is refused the same way)Retry the same call in a few minutes; if it keeps failing, contact support
CREDENTIAL_IN_MACHINE_CONFIGA Fly API token (FlyV1 …, fm2_…, fo1_…) is in the env or metadata the call supplied (the error names where, never the value) — refused before anything was created, queued or chargedDon't retry as is: store it with set_compute_secret (the server reads it at runtime), then send the call again without it. compute_rebuild takes no env — the token is in that build's saved settings: after storing it, deploy again with provision_compute_from_repo and the env without that key (it replaces the running server)
DATABASE_NEEDS_ALWAYS_ONA database or cache server is private, so its address never wakes a sleeping server. Refused before anything is queued, counted or charged (the message states the prices): a new one asked for without alwaysOn: true (scaleToZero: false on an image deploy), a request to make one sleep or to switch its always-on off, a redeploy or rebuild of one that sleeps, or of one whose server was removed while it sleptConfirm the always-on price with the user, then call again with alwaysOn: true. A sleeping one: compute_always_on {alwaysOn: true} first, then rebuild (one whose server was removed: provision_compute_from_repo with alwaysOn: true and the same repo, branch, folder and port). To pay less, stop or delete it — always-on can't be turned off for it
TRIAL_DATABASE_NEEDS_DISKA database image whose data lives on a disk (Postgres, MySQL, MongoDB, …) on the free welcome credit, which has no disk — its data would vanish on every restart. Nothing was deployed or chargedA free Supabase or Neon database under the user's own account, its URL set as DATABASE_URL with set_compute_secret; or a paid top-up (topup_link), then provision_database
TRIAL_CACHE_UNAVAILABLEA cache image (redis, valkey, memcached) on the free welcome credit: it would be the account's one server, and private (no internet address), so nothing could reach it. Nothing was deployed or chargedA Redis URL from the user's own provider (a free Upstash database) set as REDIS_URL with set_compute_secret; or add funds (topup_link) to lift the one-server limit
TRIAL_REGION_MISMATCHA database or cache server asked for a region other than the one the welcome-credit account's servers run in (the error names it). Nothing was deployed or chargedCall again without region (it goes where the others are) or with that region
DATABASE_IMAGES_UNAVAILABLElavela isn't running database or cache images as servers right now. Nothing was deployed or chargedprovision_database for Postgres, or a database URL from the user's own provider (Supabase, Neon) set with set_compute_secret; for Redis, a URL from the user's own provider
NETWORK_MISMATCHlavela refused to start a database or cache server because its app is not in the owner's own private network (it would not be private) — lavela's side, already reported; nothing was built, deployed or chargedNothing to change in the request: wait a few minutes, then compute_rebuild (or the same deploy again); if it fails the same way twice, contact support
ABUSE_HOLDlavela's own automatic hold of one server (suspected abuse, or the free trial's daily data-transfer limit): every start, restart, redeploy, resize and always-on change of it is refused; the account's other servers are not affectedNothing the user or the agent does releases it — don't retry any of them. The user contacts support (a person reviews it); the daily-transfer hold lifts by itself at 00:00 UTC
SERVICE_NAME_INVALIDA new service or resource name breaks lavela's naming rule (a service name: lowercase letters, digits and single dashes, starting with a letter, at most 20 characters; the error says how) — nothing was createdCall again with the name the error suggests, or another valid one
SERVICE_NAME_TAKENThe name is already used in this project (the error names the resource), or — for a service — it would share another service's server (service names are compared without their dashes) — nothing was createdUse the existing one (list_resources, project_overview) or call again with another name
DECLARED_SERVICE_LIMITThe project (10) or the account (5; 3 on the welcome credit) already has the most services whose server space was created but never deployedDeploy one, or remove one the user confirms is unused
ACCOUNT_NOT_FUNDEDSetting variables, pushing an image or adding a disk for a service that is not deployed yet creates server space, which needs funds (or the welcome credit) on the accounttopup_link or account_status, then the same call again
NETWORK_UNVERIFIEDlavela could not confirm which private network the service's server space is in — nothing new was created or changed; running servers are untouched; lavela has been alertedWait a few minutes, then the same call; don't retry in a loop
APP_NAME_UNAVAILABLEThe service's server name and its suffixed form are both taken at lavela's hosting provider — lavela's side, alertedContact support; retrying won't help
NETWORK_BUDGET_REACHEDThe account created the most new private networks it mayDelete a project the user no longer uses (its network is reused), then try again
NETWORK_CAPACITY_REACHEDlavela cannot create another private network right now — lavela's side, alertedTry later; don't retry in a loop
SERVICE_BUSYAnother change to the service, or another call creating the same thing, is still running, so this one changed or created nothing; a change that stopped partway needs lavela's attentionWait a minute (retry_after_ms), then call the same tool again with the same name — it returns the existing resource once it exists; an interrupted attempt frees the name within 15 minutes; for "needs attention", contact support
SERVICE_IDENTITY_CHANGEDA new server name was saved; no server or build startedRepeat the same request once; funds and limits are checked again
SERVICE_OPERATION_STALEThis change was superseded and stopped without changing anythingRead the service's state, then repeat only if still wanted
SERVICE_HAS_RESOURCESA removal would delete a server, a disk or snapshots — nothing is deleted automaticallyRemove them explicitly, with the user's confirmation
SUSPENDED, DATA_RESIDENCY, REGION_NOT_ALLOWEDOnly support can helpContact support; don't retry

Redeploy and rollback

A server built from a repo (after the user pushes, or once a failure is fixed): lavela.compute_build_status {projectId, service} returns the service's last build — pass its id to lavela.compute_rebuild. It repeats the build exactly (branch, folder, port, env, volume mounts) and fetches the branch again, so pushed code is included (a build pinned to one commit builds that commit again). The server keeps its current size and always-on setting — a resize or a switch made after the build is never undone. With no server running (it was removed, or lost), the rebuild creates it with the size and always-on setting it last ran; a build started after that server was removed, or for a service that never had one, uses its own — and on the welcome credit a removed server bigger than 512 MB comes back at the build's own size (512 MB when that is what it was built with). The build's serviceSize and serviceAlwaysOn say which. An always-on server pays its always-on price every second, while a sleeping one pays it only while awake (its asleep price otherwise), and a bigger size costs more while awake or always on (this server's prices: project_overview; all: prices) — say so when you confirm the rebuild with the user. To change only the size, lavela.compute_set_size (advanced) resizes the running server in place, no rebuild. Never redeploy with provision_compute_from_repo and guessed settings: whatever it is given replaces the running server — defaults for the rest, except the size and always-on setting, which it keeps when they are left out. To change only the port, the folder or the branch, pass internalPort, subdir or gitRef to the same compute_rebuild call (they are checked like provision_compute_from_repo's; "" for subdir / gitRef means the repo root / the default branch): everything else is repeated as above, the new build stores the change, and every later rebuild of that build repeats it — a failed build keeps it too, so rebuilding that one repeats the change. For env, use set_compute_secret / set_build_vars. When a build can't be repeated:

A server whose last build says ok but that no longer exists (it was removed) is shown by lavela.project_overview as not_running — redeploy it with compute_rebuild (it comes back as the build's serviceSize and serviceAlwaysOn say — normally the size and always-on setting it last ran; uploaded code: a new deploy_link), never report the old URL as live. A server that exists shows as deployed with live: null: lavela's records can't tell a running server from one stopped by the user or a balance pause — check_health checks it, and compute_lifecycle action start starts a stopped one.

A reclaimed server: when a welcome-credit server's machine was removed (its balance ran out and it stayed stopped, or its owner left it stopped for a long time), lavela.project_overview and lavela.compute_list show it as reclaimed (state) with reclaimedAt, appDeletesAt and its old machineId. lavela keeps its settings, image and variables until appDeletesAt: lavela.compute_lifecycle {machineId, action:'start'} recreates it exactly as it was ("Start again": no build, nothing to repeat; it needs funds and is paid from the wallet) — use it before compute_rebuild, which rebuilds from source and counts as a build. After appDeletesAt the variables and the built image are deleted: a start then rebuilds from the repository (it counts as a build) and the result lists the variables to set again (variablesToSetAgain). lavela.resume_compute only lifts a pause; it never starts or recreates a server.

Web hosting: lavela.redeploy {projectId} rebuilds the same repo, folder and branch with the env stored on the project (CONFLICT = a deploy is already running). To undo a bad deploy instantly, lavela.list_deployments → lavela.rollback {deploymentId} (advanced tools) re-points the live site without a rebuild (web hosting only — confirm with the user; it changes what is live).

Secrets: lavela.set_compute_secret restarts the running server by default (a server at rest gets them at its next start; a one-off job or a build running at that moment keeps its old values); with apply: false the next deploy picks them up. A service name nothing runs under yet starts a new service: the result says createdService: true, and warns SIMILAR_SERVICE next to a close name (wbe for web), so confirm the name with the user. unset: ["NAME", …] removes names (the running server restarts; a name that is not set is a clean no-op that restarts nothing; the same name can't be in secrets and unset in one call). A name is capital letters, digits and underscores (at most 64, not starting with a digit), a value is at most 32 KiB, and a service holds at most 100. PORT, PATH, HOME, HOSTNAME, PRIMARY_REGION, FLY_* and LAVELA_* are set by lavela and the provider and are refused (VARIABLE_RESERVED): a server's port is internalPort on a deploy. A secret value that contains ${{ … }} is refused:

ErrorMeaningWhat to do
REFERENCES_UNAVAILABLEReferences between services aren't available yet, so lavela would have stored the text literally — nothing was stored (the error names the keys)Set the real value instead (another service's private address: compute_wire)
VARIABLE_RESERVEDA secret named like something lavela or the provider sets in every server's environment (PORT, PATH, HOME, HOSTNAME, PRIMARY_REGION, FLY_*, LAVELA_*) — nothing was stored (the error names the keys, never a value)Use another name; a server's port is internalPort when deploying, not a secret

Read command audit history (lavela.compute_exec_history, advanced). Pass projectId, optional service (default web) and limit (up to 50). Returns only owned audit times, outcomes, exit codes and bounded byte/duration metadata; no command text, command output or credentials. It never runs a command or wakes a server.

Run a command in a server (lavela.exec_compute, an advanced tool). {projectId, service, cmd} runs a shell line (/bin/sh -c, at most 4 KiB) inside the service's server for up to 60 seconds; argv (the program and its arguments as a list, no shell) is for an image that has no /bin/sh. The result has exitCode, stdout and stderr — at most 64 KiB of each, then truncated: true (stdoutBytes and stderrBytes say how much there was) — and durationMs. It is free, but it only runs in a server that is already running: it never starts or wakes one and never keeps one awake. An account may run 10 commands a minute. On a server with a disk, or a database or cache server, a command can change data on the disk: confirm with the user first — dryRun: true answers (with that warning) without running anything or counting against the limit. lavela never returns a password, but a command run in your server can read its environment, so its output may show one; lavela keeps no command text and no output — each call leaves one audit record with a keyed fingerprint of the command, never the command. An account that only has the welcome credit cannot run commands yet (TRIAL_ROUTE_UNSUPPORTED).

ErrorMeaningWhat to do
MACHINE_NOT_RUNNINGThe server is stopped, suspended, starting or gone (params.state) — nothing ranAsk the user, then compute_lifecycle start, and run the command again
EXEC_NO_SHELLThe image has no /bin/sh — nothing ranCall again with argv instead of cmd
EXEC_UNAVAILABLElavela could not check the exec limit — its side, already reported; nothing ranTry again in a few minutes; if it persists, contact support
RATE_LIMITEDMore than 10 commands in a minute (the message names the wait)Wait retry_after_ms, then run it again

Conditional service control refusals

Service control features require account availability and verified provider capabilities. A documented refusal does not mean a feature is enabled. No failed verification is treated as permission to expose a port, start a held server, or allocate paid resources.

CodeMeaningFix
INVALID_SERVICE_SETTINGSChoose valid service settings and a port from 1 to 65535.Correct the request as described, refresh the owned service, and retry.
PUBLIC_DATABASE_PORTDatabase and cache services must remain private.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_PRIVATE_ONLYThis datastore template must remain private.Correct the request as described, refresh the owned service, and retry.
PRIVATE_SERVICES_UNAVAILABLEPrivate services are unavailable until their isolation and routing requirements are verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PRIVATE_SLEEP_UNSUPPORTEDKeep this private service always on until wake support is verified.Correct the request as described, refresh the owned service, and retry.
DATABASE_NEEDS_ALWAYS_ONKeep database and cache services always on.Correct the request as described, refresh the owned service, and retry.
WORKER_ALWAYS_ONWorkers must be private and always on.Correct the request as described, refresh the owned service, and retry.
PRIMARY_MUST_BE_PUBLICChoose a public service as the primary service.Correct the request as described, refresh the owned service, and retry.
SERVICE_SETTING_CONFLICTThe requested service settings conflict.Correct the request as described, refresh the owned service, and retry.
SERVICE_ROUTING_ROLLBACK_BLOCKEDThis project requires the stored service routing contract. Restore its routing settings before changing compute resources.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SERVICE_HELDStart the held service through its authorized start path before changing its configuration.Ask the owner to resolve or approve the stated requirement before retrying.
CUSTOM_DOMAIN_ATTACHEDDetach the service custom domain before making the service private.Ask the owner to resolve or approve the stated requirement before retrying.
REFERENCE_INVALIDUse the supported service reference grammar and export names.Correct the request as described, refresh the owned service, and retry.
REFERENCE_UNRESOLVEDChoose an available producer in this project.Correct the request as described, refresh the owned service, and retry.
REFERENCE_SELFA service cannot reference itself.Correct the request as described, refresh the owned service, and retry.
REFERENCES_UNAVAILABLEService references are unavailable for this account.Correct the request as described, refresh the owned service, and retry.
PROJECT_REGION_MISMATCHLinked private services must use the project home region.Correct the request as described, refresh the owned service, and retry.
PROJECT_REGION_UNVERIFIEDThe service region could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
LINK_TARGET_UNREACHABLEStart and verify the producer before linking it.Correct the request as described, refresh the owned service, and retry.
LINK_SOURCE_UNAVAILABLEThis producer has no supported, verified exports.Correct the request as described, refresh the owned service, and retry.
LINK_CONSUMER_UNSUPPORTEDChoose a compute service as the link consumer.Correct the request as described, refresh the owned service, and retry.
EXPORT_SNAPSHOT_MISMATCHThe producer routing changed; publish a verified export version before applying references.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
VARIABLE_CONFLICTChoose different variable names or explicitly authorize overwrite.Correct the request as described, refresh the owned service, and retry.
VARIABLE_LIMITKeep the service within the variable count limit.Correct the request as described, refresh the owned service, and retry.
VARIABLE_SHADOWS_ENVRemove the conflicting app environment key before applying the variable.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_MANAGED_KEYThis variable is managed by the datastore template.Correct the request as described, refresh the owned service, and retry.
VARIABLE_RESERVEDChoose a variable name that is not reserved by the platform.Correct the request as described, refresh the owned service, and retry.
INVALID_VARIABLE_INPUTUse valid variable names and bounded values.Correct the request as described, refresh the owned service, and retry.
PROVIDER_UNAVAILABLEThe real compute provider is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PROVIDER_REQUEST_FAILEDThe provider request could not be completed. No provider response body is exposed.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
DNS_PROVIDER_UNAVAILABLEThe real DNS provider is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PROVIDER_PROBE_UNAVAILABLEVerified routing capability for this project network is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ENDPOINT_PROBE_UNAVAILABLEA probe from the exact project network is required before this change.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ENDPOINT_UNVERIFIEDThe applied service endpoint could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
CUSTOM_DOMAIN_PROBE_UNAVAILABLEThe service custom-domain inventory could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SERVICE_PRICE_UNAVAILABLEThe current service price could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
DNS_OWNERSHIP_UNVERIFIEDDNS ownership could not be verified; foreign records were preserved.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
IP_ASSIGNMENT_MISMATCHThe provider IP assignment does not match the service network.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
MACHINE_STATE_UNAVAILABLEThe current service machine state could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
MACHINE_VERSION_UNVERIFIEDThe accepted machine version could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
MACHINE_CHANGEDThe machine changed during this request; refresh and retry.Correct the request as described, refresh the owned service, and retry.
SERVICE_CLASS_MISMATCHThe service machines have incompatible classifications.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
CERTIFICATE_ISSUANCE_PENDINGCertificate issuance is pending; keep the journal for a later retry.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
CERTIFICATE_UNAVAILABLEThe service certificate could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_EXPORTS_UNAVAILABLEThe current template connection exports could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SERVICE_NAME_CONFLICTChoose a producer name that is unique within this project.Correct the request as described, refresh the owned service, and retry.
APPROVALS_UNAVAILABLEThe owner-approval lane is unavailable; this change cannot proceed.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
OWNER_APPROVAL_REQUIREDThe owner must approve this exact change before it can proceed.Ask the owner to resolve or approve the stated requirement before retrying.
COST_GATE_UNAVAILABLEThe authoritative cost gate is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TRANSITION_OUTAGE_CONFIRMATION_REQUIREDConfirm the planned interruption before changing the service address.Ask the owner to resolve or approve the stated requirement before retrying.
PUBLIC_INGRESS_REMAINSPublic ingress remains; the private transition cannot proceed.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SERVICE_SETTINGS_CHANGEDThe service settings changed; refresh and retry.Correct the request as described, refresh the owned service, and retry.
REFERENCE_APPLY_FAILEDThe consumer variable apply failed and remains unacknowledged.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
REFERENCE_PROPAGATION_PENDINGConsumer acknowledgements are pending; the old route is retained.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
INVALID_OUTBOX_INTENTThe durable service work could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SERVICE_NOT_FOUNDChoose an existing service in the owned project.Correct the request as described, refresh the owned service, and retry.
SERVICE_BUSYThe service has another operation in progress.Correct the request as described, refresh the owned service, and retry.
SERVICE_OPERATION_STALEThe service operation generation is stale.Correct the request as described, refresh the owned service, and retry.
SERVICE_HAS_RESOURCESA service with machines, disks, snapshots or pending resources cannot be removed here.Correct the request as described, refresh the owned service, and retry.
BUILD_IN_PROGRESSWait for the current service build to finish.Correct the request as described, refresh the owned service, and retry.
NETWORK_UNVERIFIEDThe exact project network could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
NETWORK_MISMATCHThe service is outside its owned project network.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
CONSENT_REQUIREDAccept the current Terms before authorizing this cost.Ask the owner to resolve or approve the stated requirement before retrying.
TENANT_CAPPEDThis account is capped and cannot start additional paid work.Ask the owner to resolve or approve the stated requirement before retrying.
TENANT_SUSPENDEDThis account is suspended; contact support.Ask the owner to resolve or approve the stated requirement before retrying.
NO_CARDThe older billing plan requires a valid card before this cost can proceed.Ask the owner to resolve or approve the stated requirement before retrying.
PAYMENT_EXHAUSTEDResolve the older billing plan payment before this cost can proceed.Ask the owner to resolve or approve the stated requirement before retrying.
WALLET_CUTOVER_REQUIREDComplete the wallet billing transition before authorizing this cost.Ask the owner to resolve or approve the stated requirement before retrying.
WALLET_COMPUTE_DISABLEDWallet-funded compute is unavailable; this account cannot proceed without billing protection.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
INSUFFICIENT_AVAILABLE_BALANCEAdd available prepaid balance before authorizing this cost.Ask the owner to resolve or approve the stated requirement before retrying.
INSUFFICIENT_WALLET_BALANCEAdd available prepaid balance before authorizing this cost.Ask the owner to resolve or approve the stated requirement before retrying.
BILLING_DATA_UNAVAILABLEThe authoritative billing data is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TRIAL_SERVER_LIMIT_REACHEDThis account has reached its welcome-credit server limit.Ask the owner to resolve or approve the stated requirement before retrying.
TRIAL_ROUTE_UNSUPPORTEDThis operation is unavailable on welcome credit.Ask the owner to resolve or approve the stated requirement before retrying.
SIZE_NOT_OFFEREDChoose an offered server size.Correct the request as described, refresh the owned service, and retry.
SIZE_NEEDS_PAID_TOPUPA paid top-up is required for this server size.Ask the owner to resolve or approve the stated requirement before retrying.
PAYMENT_REQUIRES_ACTIONComplete the payment verification before proceeding.Ask the owner to resolve or approve the stated requirement before retrying.
PAYMENT_PENDINGWait for the pending payment to complete.Ask the owner to resolve or approve the stated requirement before retrying.
PAYMENT_METHOD_REQUIREDAdd an eligible payment method before proceeding.Ask the owner to resolve or approve the stated requirement before retrying.
PAYMENT_METHOD_DECLINEDUse another payment method before proceeding.Ask the owner to resolve or approve the stated requirement before retrying.
METERING_STALECurrent metering evidence is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
POLICY_NOT_CONFIGUREDThe required billing policy is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TOPUP_LIMIT_REACHEDThe top-up limit has been reached.Ask the owner to resolve or approve the stated requirement before retrying.
ALWAYS_ON_CONFIRMATION_REQUIREDConfirm the always-on price before starting this service.Ask the owner to resolve or approve the stated requirement before retrying.
WORKER_NOT_READYThe worker did not stay started through its readiness check.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PRIVATE_ADDRESS_UNVERIFIEDThe private address mode has not been verified in the exact project network.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PRIVATE_ADDRESS_AMBIGUOUSMultiple private addresses were found; the address must be reconciled before proceeding.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PRIVATE_ADDRESS_MODE_CONFLICTThe private address mode conflicts with the recorded routing proof.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PRIVATE_INGRESS_PRESENTPublic ingress remains on the private service.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SERVICE_SERVER_COUNT_UNSUPPORTEDMultiple server machines were found for this service; reconcile the one-server invariant before changing its cost.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
MACHINE_DELETION_UNVERIFIEDThe old machine deletion could not be verified; no replacement was created.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
FEATURE_DISABLEDThis feature is unavailable for this account. Do not allocate resources or bypass its availability check.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PAID_TOPUP_REQUIREDThis operation requires an eligible paid account.Ask the owner to resolve or approve the stated requirement before retrying.
FEATURE_CONSENT_REQUIREDThe owner must accept the specific current feature terms before authorizing this operation.Ask the owner to resolve or approve the stated requirement before retrying.
LEGAL_DECISION_UNAVAILABLEThe required approved feature policy is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ONDEMAND_STATE_UNKNOWNThe owned service state could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ONDEMAND_UNAVAILABLEThe requested optional service operation is unavailable. No provider error body is exposed.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
NETWORK_POLICY_RANGES_UNVERIFIEDThe current network policy ranges could not be verified. No policy change was applied.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
NETWORK_POLICY_UNVERIFIEDThe applied network policy did not pass its exact owned-network checks.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
OPAQUE_NAMES_UNAVAILABLEThe approved private app naming capability is unavailable. No app was created.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ROUTER_ADDRESS_AMBIGUOUSMultiple router-network addresses were found. Reconcile the owned route before publishing it.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ROUTER_ROUTE_INVALIDThe shared route does not match the owned service routing contract.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ROUTER_STATE_UNKNOWNThe shared router state could not be verified. Keep the stored route and reconcile the original operation.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ROUTER_TRIGGER_UNMETShared routing has not met its approved activation conditions. No router was allocated.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
WILDCARD_CERTIFICATE_UNVERIFIEDThe shared wildcard certificate could not be verified. No public route was published.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_MANIFEST_CHANGEDThe immutable template recipe changed. Refresh and review the current template before trying again.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_REVIEW_STALEThe template or its affected consumers changed after review. Refresh the plan and confirm the current operation.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_TLS_TRUST_UNAVAILABLEThe exact current template TLS trust certificate could not be verified. Do not disable certificate verification.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PUBLIC_TCP_TEMPLATE_NATIVE_UNSUPPORTEDThis private datastore recipe cannot safely expose its native port. Keep it private or use a supported external connection path.Correct the request as described, refresh the owned service, and retry.
INVALID_TEMPLATE_REQUESTUse a stable unique request identity for this exact template operation.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_MAJOR_UPGRADE_REQUIREDA major database upgrade requires a reviewed new template, safety snapshot, dump and restore, data verification and relinking. Keep the original until verification succeeds.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_UPGRADE_UNAVAILABLEA reviewed immutable same-major template update is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_OUTAGE_CONFIRMATION_REQUIREDReview the affected consumers and confirm the temporary connection outage before continuing.Ask the owner to resolve or approve the stated requirement before retrying.
TEMPLATE_ROTATION_UNCERTAINThe database password change is uncertain. Reconcile the saved request instead of sending another password change.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_LIFECYCLE_STATE_UNKNOWNThe saved template operation state could not be verified. Keep the original request identity for reconciliation.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_SAFETY_SNAPSHOT_UNAVAILABLEA verified safety snapshot is required before changing the template image.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_SAFETY_SNAPSHOT_PENDINGThe safety snapshot is not yet verified. Check the saved request before another snapshot or template update.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_UPGRADE_UNCERTAINThe template image update is uncertain. Verify the saved operation before another provider update.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_OPERATION_REQUIREDUse the reviewed template lifecycle controls for this database service. Generic settings or deployments cannot replace its managed recipe.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_SECRET_VERSION_UNVERIFIEDThe current provider secret version could not be verified. No template update was sent.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SECRET_VERSION_UNVERIFIEDThe current secret update could not be verified. No server update was sent.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SECRET_WRITE_PENDINGA previous secret update is still unresolved. Keep the original request and wait for reconciliation before updating the server.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SECRET_WRITE_SCOPE_UNVERIFIEDThe owned service and its secret update could not be verified. No secret update was sent.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TLS_HOST_INVALIDChoose a valid TLS hostname for the owned service.Correct the request as described, refresh the owned service, and retry.
PROVIDER_TIMEOUTThe provider timed out. The operation needs reconciliation before another allocation.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PROVIDER_RESPONSE_UNVERIFIEDThe provider result could not be verified. Do not repeat paid allocation.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
PORT_NOT_ALLOWEDChoose an allowed public TCP port.Correct the request as described, refresh the owned service, and retry.
PUBLIC_PRIVATE_PORT_ISOLATION_UNVERIFIEDPublic and private port isolation is unverified. Existing private consumers and ports are preserved.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ADDON_PRICING_UNAVAILABLEThe approved addon price and bounded absorption policy are unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ADDON_RUNTIME_UNAVAILABLEThe real addon runtime or exact machine inventory is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ADDON_ALLOCATION_UNKNOWNAddon allocation is uncertain. Reconcile the original operation instead of allocating another IP.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ADDON_INVENTORY_UNKNOWNThe complete owned addon inventory could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ADDON_RELEASE_UNVERIFIEDProvider addon release could not be confirmed. Billing reconciliation remains pending.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
ADDON_METER_UNAVAILABLEAuthoritative addon metering is unavailable. No provider mutation is authorized.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
APPROVAL_STALEThe reviewed state changed. Refresh the exact operation and request a new owner review.Correct the request as described, refresh the owned service, and retry.
APPROVAL_INVALIDUse an approval for this exact owned action, parameters and current state.Correct the request as described, refresh the owned service, and retry.
PUBLIC_ENDPOINT_UNVERIFIEDThe applied public endpoint could not be verified. Do not claim that the service is reachable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_RUNTIME_UNAVAILABLEThe real private template runtime is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_MANIFEST_UNAVAILABLEThe immutable template recipe and approved policy are unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
INVALID_LINK_INPUTChoose valid, owned service link targets.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_NOT_READYThe datastore template did not pass its readiness checks.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
CREDENTIAL_STORE_UNAVAILABLEThe write-only template credential store is unavailable. No credential is returned.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TLS_GENERATION_UNAVAILABLETemplate TLS credentials could not be generated safely.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SNAPSHOTS_UNAVAILABLESnapshot operations are unavailable for this account.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_VOLUME_UNVERIFIEDThe exact owned template disk could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
EGRESS_PAIR_MACHINE_LIMITReconcile the supported machine count before allocating a static egress pair.Correct the request as described, refresh the owned service, and retry.
PUBLIC_TEMPLATE_TLS_UNVERIFIEDThe immutable template TLS backend configuration could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
STORAGE_UNAVAILABLEThe real owned storage operation is unavailable. No provider error body is exposed.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
STORAGE_NEEDS_ATTENTIONThe storage operation requires reconciliation. Do not repeat replacement or allocation.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
VOLUME_EXTEND_UNAVAILABLEDisk extension is unavailable for this account.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
VOLUME_NOT_FOUNDChoose an existing disk of the exact owned service.Correct the request as described, refresh the owned service, and retry.
VOLUME_SIZE_INVALIDChoose a valid disk size within the supported limits.Correct the request as described, refresh the owned service, and retry.
VOLUME_SHRINK_UNSUPPORTEDDisks can only grow. A smaller replacement requires an explicit data migration.Correct the request as described, refresh the owned service, and retry.
VOLUME_CAPACITY_REQUIREDThe requested physical disk capacity exceeds the approved limit. Keep the existing disk and review capacity.Ask the owner to resolve or approve the stated requirement before retrying.
SNAPSHOT_SETTINGS_INVALIDChoose at least one valid future snapshot setting.Correct the request as described, refresh the owned service, and retry.
SNAPSHOT_SETTINGS_UNAVAILABLEThe authoritative snapshot settings or template policy could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
TEMPLATE_SNAPSHOT_REQUIREDThis template requires daily snapshots and its minimum retention. Keep its required protection.Correct the request as described, refresh the owned service, and retry.
TEMPLATE_SNAPSHOT_POLICY_REQUIREDDisabling optional template snapshots requires its exact approved owner review and policy.Ask the owner to resolve or approve the stated requirement before retrying.
SNAPSHOT_INVENTORY_UNKNOWNThe complete snapshot inventory could not be verified.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
SNAPSHOT_NOT_FOUNDChoose an existing snapshot of the exact owned disk.Correct the request as described, refresh the owned service, and retry.
RESTORE_CAPACITY_REQUIREDOld, new and pending disks all count. Review the required physical capacity before restoring.Ask the owner to resolve or approve the stated requirement before retrying.
STORAGE_RESTORE_UNAVAILABLEThe real encrypted restore runtime is unavailable.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
INSPECT_UNAVAILABLEPositive isolated inspection containment is unavailable. No inspection server is created.Do not bypass the check or allocate resources; contact support if verification remains unavailable.
APPROVAL_REQUIREDThe owner must review and approve this exact action before it executes.Ask the owner to resolve or approve the stated requirement before retrying.

Persistent data

A server's own disk is ephemeral: everything the app writes there — SQLite files, uploads, JSON/file stores, file sessions — is wiped on every redeploy, restart, and sleep/wake — tell the user so when a deploy goes live. An app that keeps any state needs one of:

These need a funded account (not the welcome credit). Managed Postgres has no usage charge today — a per-account limit bounds it. On the welcome credit, or to keep the data with a provider of your own: Bring your own database.

When creating a disk or a database is refused (nothing was created or charged):

ErrorMeaningWhat to do
VOLUME_NEEDS_BALANCEA new disk may need about 30 days of its price available on the balance (the error states the amount), and nothing owed — checked only while lavela's disk balance check is onTell the user the amount, have them add funds (topup_link), then call again — or choose a smaller disk
VOLUME_LIMIT_REACHEDThe account's disk limit: the error says whether it is the number of disks or the total GB (every disk counts, attached or not), or that new disks are closed for the accountFree a disk the user no longer needs (list_resources → destroy_resource, with their agreement: its data is deleted; remove the server using it first), choose a smaller size, or contact support to raise the limit — when the error says new disks are closed, only support can open them
VOLUME_GLOBAL_LIMIT, VOLUME_LIMITS_UNAVAILABLElavela can't create new disks right now: its own disk capacity is full (VOLUME_GLOBAL_LIMIT) or its disk limits couldn't be read (VOLUME_LIMITS_UNAVAILABLE) — lavela's side, not the account'sDon't retry in a loop: tell the user and try again later; contact support if it persists
VOLUME_IN_USEdestroy_resource of a disk a server still uses — nothing was deletedRemove the server that uses it first (destroy_compute, with the user's confirmation), then delete the disk; a redeploy without mounts keeps it attached
MANAGED_DB_LIMIT_REACHEDThe account's limit on lavela databases (a hosted app's own database and ones left by deleted projects count; the error names those, with their ids). "… closed … right now" means deleting one frees nothingFree one the user no longer needs (destroy_resource, with their agreement: its data is lost), or store a Postgres URL from the user's own provider as DATABASE_URL with set_compute_secret (Bring your own database)
MANAGED_POOL_FULLlavela's own database capacity is full right now — not the account's limitA Postgres URL from the user's own provider (Bring your own database), or try later
MANAGED_CACHE_UNAVAILABLElavela creates no Redis databases of its ownA Redis URL from the user's own provider, stored as REDIS_URL with set_compute_secret — or run redis or valkey as the user's own server (see Redis above)
SERVICE_NOT_FOUNDwireToService names no server of this project (a typo)Use a name project_overview shows, or deploy that server first

Reaching another service. All of an account's servers, in every project, share one private network. One server reaches another at <app>.internal on the port it listens on (compute_wire gives the address). That address answers only while the server runs: nothing wakes a server that sleeps when idle, or a stopped one, through it — so a database or an internal API that other services call must be always on (compute_always_on; it costs more — confirm with the user). The server must also listen on IPv6 (::): an app bound to 0.0.0.0 only can't be reached there. A one-off job or a build of that service shows up at the same address while it runs, so a connection can occasionally be refused — retry it.

Migrations: run_compute_job with the app's image — a job that outlasts ~180 seconds keeps running in the background on its own server, which stays billed (asleep once the job ends) until destroy_compute removes it; don't run it twice (pass the same idempotencyKey on a retry).

Bring your own database

Create a free Supabase or Neon database under your own account and set DATABASE_URL with set_compute_secret before or after your first deploy.

Set the whole connection string as the value: ${{ … }} references between services aren't available yet (REFERENCES_UNAVAILABLE).

Domains

lavela.provision_domain connects a domain the user already owns — lavela doesn't sell domains — and returns the DNS records to add at their registrar. target: "hosting" (default) attaches it to the web-hosting site, which verifies and gets HTTPS by itself once the records propagate. target: "compute" attaches it to a server (service, default web), which doesn't verify by itself — poll get_status. The app must be deployed first.

lavela.diagnose_domain checks each expected record against DNS and the HTTPS certificate, and returns a fix list in plain words:

Record statusMeaning
verifiedFound, correct
propagation_pendingNot visible yet — DNS changes usually take 10–30 minutes, sometimes hours; check again later
wrong_targetA record exists but points somewhere else — change it to the expected value
txt_conflictSeveral TXT values at that name and none is the expected one — add the expected value
check_failedThe lookup itself failed — try again

The certificate is issued, not_yet (usually follows the records within minutes) or check_failed (couldn't check — try again). A common mistake: registrars that append the domain to the name themselves turn www.example.com into www.example.com.example.com — enter only www.

Email

lavela.provision_email sets up DKIM / SPF / DMARC on a domain the user owns (needs a funded account). Ownership is proven automatically when the domain is this project's live connected domain (provision_domain, DNS pointing at it) — its records are then published automatically. Otherwise the result carries an ownershipVerification TXT record: the user publishes it, then call provision_email again (nothing is set up for the domain until then), and publish the records it returns. lavela-owned domains (lavela.dev and subdomains) are refused. Poll get_status for verification.

send_email (advanced) sends from an address on that verified domain. Pass the same idempotencyKey on a retry so nothing is sent twice. EMAIL_DAILY_CAP: the daily limit is reached (lower for accounts under 14 days old; an account with only the welcome credit can't send email until a paid top-up) — wait for the reset. EMAIL_RATE_LIMIT_UNAVAILABLE: retry in a few minutes.

Email on the welcome credit. provision_email and send_email are refused there (TRIAL_ROUTE_UNSUPPORTED, action email_send) until a paid top-up. Meanwhile the app can send its own mail with the user's own Resend account: its API key set with set_compute_secret (for example RESEND_API_KEY).

Payments

lavela.connect_stripe lets the user's app take payments — confirm with the user first; it starts Stripe's identity checks (KYC, commonly 1–5 days). mode: "oauth" connects an existing Stripe account (it can be unavailable — then use mode: "new"); mode: "new" creates one with embedded onboarding. Poll get_status for the onboarding link and KYC state. If the user already has Stripe connected on another of their projects, mode: "new" answers status: "choice_required" with options and starts nothing — ask whether to reuse one (reuseAccountId) or create a separate account (forceNew: true). A revoked Stripe module means payments are broken until reconnected.

lavela.create_checkout creates a Checkout link for the user's customers. The charge runs on the user's connected Stripe account and settles to them in full — lavela takes no per-charge fee and is not the merchant. It needs KYC complete. amountCents is the smallest currency unit (1999 = $19.99) — except zero-decimal currencies (JPY, KRW, VND, CLP and the others Stripe lists), where it is the raw amount (5000 = ¥5,000). Getting this wrong overcharges real customers about 100x and Stripe can't catch it: confirm the price and currency with the user first. mode: "subscription" with an interval makes a subscription. Pass an idempotencyKey when retrying.

Money

Destructive actions

Before any of these, show the user the exact target — the project's name, the server, the resource — and wait for their confirmation.

ToolRemovesKeeps
delete_projectThe project, its servers, its disks and their snapshots at once (with all data on them), its web-hosting deployment and its email domain — irreversible. Refused while an ad campaign is live (pause it first)Managed databases, caches and storage, unless the operator enabled data release (the result's dataKept says which) — to delete them, do it BEFORE deleting the project: list_resources → destroy_resource (advanced)
destroy_computeOne server: it stops being charged. Its own disk is lostAn attached volume (still billed), its daily snapshots and managed databases stay until you delete them or the project
destroy_resourceA managed database/cache/storage/error-tracking project, or a volume, with ALL its data. A volume (disk) is deleted now; Fly keeps its daily snapshots for their retention (5 days by default), which cannot be restored through lavela, and then deletes them— A hosted app's live database (usedBy: "hosted_app") is refused unless confirmHostedAppDatabase: true after the user explicitly agreed
rollbackNothing — it changes which deployment is liveEverything
archive_projectNothing — it only hides the project; servers keep running and being chargedEverything
preview_destroy, schedule_deleteA preview environment / a cron scheduleThe project

lavela itself requires a few confirmations in an agent's request, and you cannot skip them: delete_project needs the project's exact name in confirmName (a mismatch is refused); ads_launch and ads_set_budget need the daily budget repeated (confirmDailyBudgetCents, confirmNewDailyBudgetCents); destroy_resource on a hosted app's live database needs confirmHostedAppDatabase: true; and only the user can accept the Terms (in the browser), add funds and turn on automatic top-up (in the console). These requirements only make sure the request repeats the target or amount; they show the user nothing. lavela adds no other confirmation prompt to your requests, so the confirmation above is yours to get.

Four advanced tools are also marked destructive in the tool list, so an MCP client asks before each call: exec_compute (a command can change a server's data), run_compute_job (a job changes data and is billed), ads_launch (a live campaign spends real money daily) and send_email (a sent email cannot be recalled). Confirm the exact target with the user — the server and command, the daily budget, the recipients — before calling them.

Advanced tools

Connect with https://console.lavela.dev/api/mcp/all (Connect) for these: lavela.trial_claim_link, lavela.ping, lavela.capabilities, lavela.list_templates, lavela.configure_service, lavela.link_services, lavela.volume_extend, lavela.volume_snapshots, lavela.template_status, lavela.template_rotate, lavela.template_upgrade, lavela.template_lifecycle_status, lavela.compute_exec_history, lavela.volume_restore, lavela.public_port_link, lavela.egress_ip_link, lavela.compute_status, lavela.compute_list, lavela.compute_estimate, lavela.provision_compute, lavela.push_image, lavela.compute_set_size, lavela.compute_wire, lavela.run_compute_job, lavela.schedule_create, lavela.schedule_list, lavela.schedule_update, lavela.schedule_delete, lavela.schedule_run_now, lavela.preview_list, lavela.preview_destroy, lavela.preview_webhook_setup, lavela.exec_compute, lavela.provision_storage, lavela.provision_volume, lavela.destroy_resource, lavela.send_email, lavela.billing_setup_card, lavela.archive_project, lavela.unarchive_project, lavela.compliance_generate, lavela.compliance_list, lavela.security_scan, lavela.security_scan_status, lavela.list_security_scans, lavela.provision_error_tracking, lavela.get_errors, lavela.daily_brief, lavela.list_deployments, lavela.rollback, lavela.ads_platforms, lavela.ads_draft, lavela.ads_launch, lavela.ads_status, lavela.ads_pause, lavela.ads_provision_account, lavela.ads_assets_push, lavela.ads_setup_tracking, lavela.ads_report, lavela.ads_conversions, lavela.ads_set_budget, lavela.ads_commission.

Errors and support

A tool error is { "error": { "code", "reason", "actor", "message", "user_action"?, "say"?, "docs_url", "retry_after_ms"? } }. Most carry user_action: do what it says first — the fix is usually self-serve (a link the user opens, a retry, another tool) — and don't retry in a loop when the user must act first. When it is missing, use the table below; a malformed call can also fail with a protocol error outside this shape.

CodeMeaning
FORBIDDENA policy, limit, trial or balance refusal — don't retry as-is; user_action names the fix
UNAUTHORIZEDThe connection isn't signed in (or the sign-in expired) — reconnect lavela in the client
NOT_FOUNDWrong id (also a bare CROSS_TENANT refusal: a mistyped id, or one that belongs to another account) — copy ids from list_projects / project_overview instead of retyping them
RATE_LIMITEDWait retry_after_ms, then retry the same call
CONFLICTSomething is already in progress — poll it and let it finish
BAD_REQUEST, INVALID_INPUTFix the input as the message says — also a request lavela refuses until the call changes (SERVICE_NAME_INVALID, DATABASE_NEEDS_ALWAYS_ON: reason and user_action say how); never retried as is. An INVALID_INPUT whose message names nothing wrong with what you sent is a fault: read back first (launch_saas: list_projects) so a repeat doesn't create a second project
INTERNALA problem on lavela's side — nothing in the call was wrong. A read-only or repeat-safe (idempotent) tool: retry the same call once. A tool that creates or changes something (launch_saas, a deploy, an ad launch, a delete, …) may have gone through before the error came back, so don't repeat it blindly: its user_action names the tool that shows the result (list_projects, project_overview, get_status, list_resources, ads_status, …) — call it again once only if the effect is missing. If it fails again, stop and tell the user (say) — support is the way on

CONSENT_REQUIRED: the user accepts the current Terms at /consent — once, and again when a new version requires it — then retry. A missing permission (scope): reconnect to refresh it — or, for a static token, the user creates one that has it (Manage connections).

Still stuck? Email support@lavela.dev or open /support — a person reads it, not a bot.

Questions? Email support@lavela.dev · Terms · Privacy · Credits & Refunds

lavela MCP tools — lavela