Failure semantics: refused and misconfigured requests
What happens when a request is refused, unscoped or misconfigured. Most cases fail closed. Where one fails open, or fails without an error, the Status column says so.
Access policy
| When | What you see | Status |
|---|---|---|
A PolicyRule whose filter_match is not exactly $user.email, $user.uuid or $user.name | The owner filter is skipped and the rule matches every record its other conditions allow. A warning is logged on the server; the caller sees no error. | Fails open. The value is not checked when the policy is saved. |
A role with default_access="none" and no rule for an entity, or an explicit can_read=False | Writes are refused. Reads are not refused on Supero Cloud today: the read check logs a would-deny and returns the records. | Fails open for reads until the read check is switched to enforce. Restrict reads with owner scoping (filter_field / filter_match) and hidden fields, and test reads as each role. |
Connectors
| When | What you see | Status |
|---|---|---|
| A bound connector table with no tenant binding, or a caller whose tenant does not match a fixed binding | HTTP 403 tenant_binding_missing (or a tenant mismatch 403). No query reaches your database. | Fails closed, by design. |
| A column removed or renamed in the source after discovery | Live reads of that table fail with 502 source_query_failed; the error does not name the column. New columns are ignored until you re-run discovery. On REST sources a missing key comes back as null. | Fails closed, but the error does not name the column. Re-run discovery after a source schema change. |
| A warehouse structured read that hits the 10,000-row cap | The read succeeds with the first 10,000 rows and source_meta.scan set to partial. run_query fails with 413 instead. | By design. Read the flag, or use db_stats / db_count_by so the aggregate runs in the warehouse. |
| A warehouse query still running at the 90-second deadline | Supero returns a structured error and sends a best-effort cancel. Snowflake and ClickHouse also get a server-side timeout; Databricks, BigQuery and Redshift do not, so compute can continue until the cancel lands. | By design. BigQuery’s maximumBytesBilled (100 GiB unless you set it) is the only cost limit. |
A sync table set to refresh on a schedule | Nothing runs on the schedule. Webhook and manual runs work. | Fails without an error: the scheduler is built but switched off in Supero Cloud. |
run_query (the SQL console) on a warehouse connector without read_only_attested | HTTP 403 read_only_attestation_required. | By design. It also needs a fixed tenant binding. The flag is your declaration: Supero does not inspect the role’s grants, so give it SELECT only, with no table-creation or external-function rights (url(), s3(), remote()), which the SQL guard cannot see through. |
Platform
| When | What you see | Status |
|---|---|---|
| Any request on Supero Cloud | No platform audit record is written: audit logging has been off in production since 2026-09-09. | Fails without an error. Keep your own audit log until it is back on. |
| Asking the built-in AI agent a question | Fields the asker can read are sent to the agent’s model, DeepSeek deepseek-chat on Supero Cloud. Fields their role cannot read are removed first; field names are not. | By design. For regulated data, decide before you turn the agent on, or use your own agent over MCP. |
Services and workflows
| When | What you see | Status |
|---|---|---|
A refused state transition through /api/v1/services/execute (for example place_order on a cancelled order) | HTTP 200 with success: false and status_code: 409 in the body. | Known behaviour. Check success, not the HTTP status. |
Calling a service that is not imported in the project (including services.ai) | HTTP 200 with success: false and an error naming the service; status_code is empty. The browser client does not throw. | Known behaviour. Check success and the error text. |
An event binding whose @create:ns:type reference matches no schema | The deploy prints a warning and continues. At run time the event fires nothing, and the server logs it only at debug level. | Fails without an error at run time. Check the deploy output for the warning. |
| A workflow step that fails | Depends on the step’s on_error: stop, continue, retry, or compensate, which undoes the completed steps in reverse order using each step’s compensating operation. | By design. |
Integrations
| When | What you see | Status |
|---|---|---|
stripe_checkout with no stripe_webhook_secret | Checkout takes the payment, but Supero refuses every Stripe event with a 503, so orders stay pending. The only trace is an error in the service logs. | Fails without an error. Set the secret before launch and run one test payment end to end. |
| Two tenants in one project using the same integration | Both use the same vendor credentials: one Stripe account, one Twilio account. | By design: credentials are per project. Give a tenant that needs its own account its own project. |
SDK
| When | What you see | Status |
|---|---|---|
ApiLib(enable_encryption=True) on supero 3.7.9 from PyPI | ImportError: Encryption module not available. | Packaging bug: the encryption module was left out of the wheel. The fix ships in the next SDK release. |
Reading encrypted records through an ApiLib client without the key | A single-record read raises an error that names the encrypted fields. List and bulk reads leave those records out without an error. | By design. Test both paths. |
Mistakes in your own code are on the gotchas page.