--json, the error response carries an UPPER_SNAKE_CASE code field to branch on.
Error response format
{
"success": false,
"error": {
"code": "NOT_AUTHENTICATED",
"message": "Not logged in.",
"suggestion": "Run 'floo auth login' to authenticate."
}
}
--json output is exactly what the API returned. When this page and a message disagree, the --json error envelope is the authority. The CLI also emits internal codes for transport, update, and checksum failures that are not listed here.
Error codes
Authentication
| Code | Description | Fix |
|---|---|---|
NOT_AUTHENTICATED | No stored credentials or expired API key | Run floo auth login |
DEVICE_CODE_EXPIRED | Device code expired during browser auth | Run floo auth login again |
DEVICE_AUTH_DENIED | User denied authorization in browser | Run floo auth login again |
WAITLISTED | Account is on the waitlist | You’ll be notified when access is granted |
INSUFFICIENT_KEY_SCOPE | API key doesn’t have the required scope | Use a key with the required scope |
Deploy and build
| Code | Description | Fix |
|---|---|---|
NO_CONFIG_FOUND | No floo.app.toml found | Run floo init to create config |
CONFIG_INVALID | Preflight validation failed (invalid ports, duplicate or invalid service names) | Fix the errors and run floo preflight. Service names use lowercase letters, digits, and hyphens only. |
CONFIG_EXISTS | floo init found an existing floo.app.toml, floo.service.toml, or legacy floo.toml | Edit or migrate the existing config |
DEPLOY_FAILED | Build or deploy process failed | Check error.message and build logs |
DEPLOY_TIMEOUT | Deploy timed out after 10 minutes | Check status with floo deploys list |
DEPLOY_NOT_FOUND | Invalid deploy ID | Check with floo deploys list |
DEPLOY_IN_PROGRESS | Another deploy is already running | Wait for it to finish or check floo deploys list |
RESTART_FAILED | App restart failed | Run floo logs for details |
ROLLBACK_IMAGE_MISSING | Rollback target has no stored image | Choose a different deploy to rollback to |
ROLLBACK_ENVIRONMENT_MISSING | Rollback target has no environment | Deploy first before rolling back |
PREVIEW_MANAGED_SERVICE_ISOLATION_UNAVAILABLE | floo could not provision preview-owned managed resources for a preview | Fix the attached managed-service state, then push a new commit or re-run the command |
MISSING_REQUIRED_ENV_VAR | A service’s env.required names a variable that is unset in the target environment | Set it: floo env set <NAME> --stdin --app <app> --env <env> --service <service> (the message names the service, environment, and missing keys), then redeploy |
UNKNOWN_MANAGED_ENV_ATTACHMENT | env.managed names a handle the app does not own, such as redis:cache with no such managed service | Declare the [managed.<name>] block or run floo services add, or remove the handle |
Apps
| Code | Description | Fix |
|---|---|---|
APP_NOT_FOUND | No app matches the given name or UUID | Check the name with floo apps list |
MISSING_APP_NAME | App name required in non-interactive mode | Provide a name: floo init my-app |
APP_CONSUMER_NAME_TAKEN | Consumer name already exists in the app | Choose another name or use the existing consumer |
APP_CONSUMER_CAP_REACHED | App has 50 consumers | Delete an unused consumer before creating another |
APP_CONSUMER_KEY_CAP_REACHED | Consumer has 100 active keys | Revoke an unused key before creating another |
INVALID_SCOPE_LABEL | Scope label is invalid | Correct the scope named in the error |
APP_CONSUMER_NOT_FOUND | Consumer name or ID not found in the selected app | Check with floo apps consumers list |
APP_API_KEY_NOT_FOUND | App API key ID not found in the selected app | Check with floo apps keys list --consumer daily-report, substituting your consumer |
APP_DELETING | App is being deleted | Select an active app |
GitHub
| Code | Description | Fix |
|---|---|---|
GITHUB_APP_NOT_INSTALLED | No floo GitHub App installation on the repo’s owning account | A human must open the setup link, authorize floo, and install the App on that account. connect opens the link and waits; --no-browser or --json prints the link and instructions, then exits. |
GITHUB_REPO_NOT_IN_INSTALLATION | App installed but does not have access to this repo | Open installation settings to add the repo |
GITHUB_ALREADY_CONNECTED | App is already connected to a GitHub repo | Disconnect first: floo apps github disconnect |
GITHUB_REPO_NOT_ACCESSIBLE | An installation claims the repo but GitHub refuses to read it | Check the floo GitHub App installation on the repo’s owner, whether that is an organization or a personal account (github.com/settings/installations for a personal account): confirm the repo is selected and the installation is not suspended, then run floo apps github setup |
GITHUB_NOT_CONNECTED | App is not connected to any GitHub repo | Connect first: floo apps github connect owner/repo |
GITHUB_INSTALLATION_NOT_AUTHORIZED | The App is installed on the GitHub account but not linked to your floo org | Run floo apps github setup and authorize floo through its link |
Services
| Code | Description | Fix |
|---|---|---|
SERVICE_NOT_FOUND | No service with that name | Run floo services list to see available services |
DUPLICATE_SERVICE_NAMES | Two services share a name | Choose a different name in floo.app.toml |
MANAGED_SERVICE_NOT_FOUND | No managed service of that type and name on the app | Run floo services list to see what is provisioned |
MANAGED_SERVICE_ALREADY_EXISTS | A managed service of that type and name already exists | floo services add is idempotent and never raises this; it surfaces when the API is called directly with conflicting state |
INVALID_TIER | A legacy --tier value is invalid | Ignored; see Postgres → Compute and limits |
CRON_JOB_NOT_FOUND | No cron job with that name on the app | Check the name with floo cron list |
Releases
| Code | Description | Fix |
|---|---|---|
RELEASE_NOT_FOUND | No release with that ID | Check with floo releases list |
RELEASE_TAG_EXISTS | A release with that tag already exists | Use --tag with a different tag |
NO_DEV_DEPLOY | No deploy to promote | Deploy first: floo redeploy |
NO_PROMOTABLE_SERVICES | The latest live dev deploy has no image to promote | Check floo deploys list for a live dev deploy, then promote again |
Config and IO
| Code | Description | Fix |
|---|---|---|
INVALID_PATH | The deploy path is not a valid directory | Verify the path exists and is a directory |
INVALID_FORMAT | Input format is wrong (e.g., KEY=VALUE missing =) | Check the expected format in the command docs |
CONFIG_ERROR | Cannot read or write ~/.floo/config.json | Check file permissions (should be 0600) |
PARSE_ERROR | Unexpected API response or invalid input | May indicate CLI/API mismatch, run floo update |
FILE_ERROR | Cannot read or write a file | Check the file path and permissions |
INVALID_ROLE | Invalid org member role | Valid roles: admin, member, viewer |
ENTERPRISE_SSO_REQUIRED | floo orgs sso needs an Enterprise organization plan | Contact sales@getfloo.com |
CANNOT_DETERMINE_IP | floo could not determine your public IP address when creating a floo dev session | Check your network connection, then re-run |
INVALID_AMOUNT | Invalid spend cap amount | Use a value between $0 and $1,000,000 |
INVALID_PROJECT_CONFIG | floo.app.toml or floo.service.toml failed to parse or validate: an unknown key, a wrong type, a missing type or port, or an invalid env or managed handle | Fix the key the message names; an unknown key can also mean the CLI is older than the config, so try floo update |
LEGACY_CONFIG | A legacy floo.toml was found | Migrate to floo.app.toml (plus floo.service.toml for delegated services); see the config spec |
MISSING_PORT | floo dev found a service with no port in floo.app.toml | Add port = <number> to that [services.<name>] block |
MISSING_ARGUMENT | floo skills install ran with neither --path nor --print | Pass --path <dir> to install, or --print to write to stdout |
SERVICE_CONFIG_MISSING | A delegated service declared in floo.app.toml has no floo.service.toml in its directory | Add the file, or declare the service inline instead |
NO_DEPLOYABLE_SERVICES | floo.app.toml declares only managed services | Add a [services.<name>] block with type, port, and path |
CONFIRMATION_REQUIRED | A destructive command ran without a confirmation, in --json mode or without a terminal | Pass --yes for a tier-2 command, or --yes-i-know-this-destroys-data for a tier-3 command that destroys data |
SECRET_REVEAL_REQUIRED | floo env get refused to print a secret-shaped value in plaintext | Re-run with --reveal-secrets |
ENV_VAR_WRITE_ONLY | The value was stored with --secret, so the API never returns it | Overwrite it with a new value or unset it; deploys still receive it |
UPDATE_PERMISSION_DENIED | floo update cannot write to the install path | Re-run with permissions to write that path, or reinstall with curl -fsSL https://getfloo.com/install.sh | bash |
Domains
| Code | Description | Fix |
|---|---|---|
DOMAIN_NOT_FOUND | No domain with that hostname on this app | List them with floo domains list |
DOMAIN_VERIFICATION_FAILED | DNS verification for the domain failed | Compare both DNS records with floo domains show app.example.com --app my-app, correct them, then run floo domains watch app.example.com --app my-app |
DOMAIN_WATCH_TIMEOUT | floo domains watch gave up before the domain became active | DNS changes can take up to 24 hours; re-run floo domains watch to resume |
Billing
| Code | Description | Fix |
|---|---|---|
PLAN_FEATURE_ACCOUNTS | Accounts mode requires Pay as you go or above | Upgrade at Billing |
PLAN_FEATURE_SSO | Enterprise SSO is a sales-assisted feature, not a self-serve access_mode | Contact sales@getfloo.com |
SSO_NOT_CONFIGURED | Enterprise SSO is not configured for self-serve use | Contact sales@getfloo.com |
SPEND_CAP_EXCEEDED | Monthly spend cap reached under freeze_new_spend or hard_stop; deploys and new spend are blocked | Raise the cap with floo billing spend-cap set, or wait for the next billing period |
PREPAID_HARD_LIMIT_REQUIRED | Prepaid paygo was given a zero cap or a weaker policy | Set a positive cap; prepaid always uses hard_stop |
SPEND_AUTHORITY_EXHAUSTED | Prepaid spending authority is unavailable or exhausted | Inspect floo billing balance and binding_authority; add funds or raise the limit as required |
SPEND_CAP_EXCEEDS_PLAN_LIMIT | Cap exceeds plan’s maximum | Upgrade to raise your limit |
SPEND_CAP_POLICY_REQUIRED | A non-zero cap was sent with the policy off | Choose alerts_only, freeze_new_spend, or hard_stop; see Billing and spend caps |
RATE_LIMIT_EXCEEDED | Too many API requests for the org’s plan in the current window | Wait for the seconds in the Retry-After header, then retry |
Logs
| Code | Description | Fix |
|---|---|---|
LOGS_UNAVAILABLE | Log service not configured | Contact team@getfloo.com |
LOGS_QUERY_ERROR | Invalid log query parameters | Check --since format and --severity value |
LOGS_SERVICE_ERROR | Log backend failure | Retry; the error is transient |
Handling errors in agents
RESULT=$(floo redeploy --json 2>/dev/null)
SUCCESS=$(echo "$RESULT" | jq -r '.success')
if [ "$SUCCESS" = "true" ]; then
URL=$(echo "$RESULT" | jq -r '.data.deploy.url')
echo "Deployed to $URL"
else
CODE=$(echo "$RESULT" | jq -r '.error.code')
case "$CODE" in
NOT_AUTHENTICATED)
floo auth login --api-key "$FLOO_API_KEY"
;;
NO_CONFIG_FOUND)
echo "Run 'floo init' first"
;;
DEPLOY_FAILED)
echo "$RESULT" | jq -r '.error.message'
;;
esac
fi
Exit codes
| Exit code | Meaning |
|---|---|
0 | Success |
1 | Error (check JSON error response for details) |
2 | Invalid arguments or usage; with --json, the error code is INVALID_ARGUMENTS |