Frequent CLI and API failures, organized by what you'll see in your terminal. For deeper verbose output on any command, set TERRANTULA_DEBUG=1 — the CLI then prints the full error body (API errors) or stack trace (local errors) instead of the one-line summary.
Error: no API token providedSymptom
Cause — terrantula login reads the token from the global --token flag or the TERRANTULA_TOKEN environment variable. It does not accept a --token after the login subcommand.
Fix — pass the token before the subcommand, or via the environment:
The token is saved to your config file with 600 permissions. Only the prefix is ever displayed; the full value is never logged.
Error 401 on any authenticated commandSymptom — a project- or org-scoped command returns Error 401: ....
Cause — the saved token is missing, expired, revoked, or doesn't carry the permission the route requires (project API tokens are RBAC-scoped — a read-only token can't write).
Fix
terrantula login with a valid token.*:write permission; see RBAC roles & permissions.terrantula login --base-url …).Run terrantula login first (no API token + base URL configured)Symptom — emitted by diagnostic commands such as terrantula github diagnose.
Cause — no base URL and token are saved, and none were passed via --base-url / --token.
Fix — run terrantula login (with a global --token and --base-url) once; subsequent commands reuse the saved config.
No project specifiedSymptom
Cause — commercial (server-backed) commands need a project ID. The CLI resolves it in this order: --project flag → global --project → TERRANTULA_PROJECT_ID env → the default set by terrantula use.
Fix — set a default for the session, or pass the flag explicitly:
In CI, prefer the env var so no saved login is required:
No org specifiedSymptom
Cause — same resolution chain as project, for the org slug: --org → global --org → TERRANTULA_ORG_ID → saved org.
Fix — set TERRANTULA_ORG_ID or pass --org <slug>. Note: import-atmos defaults the org/project to the local-mode sentinel terrantula when none is given, so it can run against a local DB without a login; import terraform does not — it always requires a real org and project because it's a server-backed flow.
Error 422 from an apply or SDK callSymptom — the server rejects an apply bundle, or a specific item appears under Failed in the apply output:
Cause — the declaration is structurally valid YAML but violates a server-side rule: an unknown entityType, an invalid lifecycle state transition, a relationship pointing at a non-existent entity, or a constraint violation.
Fix
Read the per-item error string — it names the field that failed.
Confirm the referenced kinds exist. Apply the catalog (EntityTypes, RelationshipTypes, Cells) before the data (Entities, Relationships). The Catalog Schema Reference documents the required fields per kind.
Re-run with --dry-run (alias --plan) to see the computed diff without writing:
Error 404 from a project-scoped callSymptom — Error 404: ... from an entity/relationship/cell operation.
Cause — usually a wrong org/project/env triple, or referencing an entity by a name that doesn't exist in that environment. Environment matters: every data call is env-scoped and defaults to default.
Fix — confirm --env (or TERRANTULA_ENV_NAME) matches the environment the data actually lives in, and that the org/project pair is correct.
Hint: this cell's membership is computed from a propertySymptom — adding a member to a cell fails with a CELL_MEMBERSHIP_DERIVED hint.
Cause — the cell is a derived cell: membership is computed from an entity property, not set directly. The UI is a read-only projection and the API enforces the same rule.
Fix — change the underlying property through an Action (which opens a PR), not by adding the member directly:
Only explicit cells accept direct membership writes. See Cell.
error: --port must be a number between 1 and 65535Cause — a non-numeric or out-of-range --port value.
Fix — pass a valid port, or omit --port to bind a random free port:
Symptom — terrantula dashboard exits with a bind error mentioning the port.
Cause — another process holds the port you requested.
Fix — drop --port so the CLI picks a free port automatically, or choose a different one. The dashboard prints the resolved URL (✓ Dashboard ready at http://…) on success.
The dashboard renders a projection of your imported state. It never writes entity properties, lifecycle states, or relationships — those changes flow through Actions → PRs → your CI. If the dashboard shows nothing, the import probably mapped 0 entities: see Import/ingest issues.
TerrantulaError shape (status, body, message).