Skip to main content

Storage error codes (mpbx-storage, PostgreSQL)

Codes raised by mpbx_storage::pg (W1-PBX-02). Kinds map to HTTP statuses in the API layer as for the common codes. Messages name at most a constraint; they never contain row values, so no personal data or secrets reach logs or API responses.

CodeKindMeaningWhat to do
MPBX-VERSION-MISMATCHconflictOptimistic locking: the row changed since you read it (the message gives the expected and current version).Reload the object and apply your change again.
MPBX-PG-DUPLICATEconflictA unique rule rejected the write, for example an extension number already used in this company. The message names the constraint.Pick another value.
MPBX-PG-REFERENCEinvalid_argumentA reference points to a row that does not exist in this company, or a row is still referenced and cannot be deleted.Check the referenced id and tenant; delete dependants first.
MPBX-PG-CONSTRAINTinvalid_argumentA value breaks a CHECK or NOT NULL rule (bad slug, bad number format), or a published call-flow version was modified.Fix the value. Published flow versions are immutable: publish a new version.
MPBX-PG-RETRYconflictSerialization failure or deadlock between concurrent transactions. Retryable.Retry the operation.
MPBX-PG-UNAVAILABLEunavailablePostgres is unreachable, restarting, or the pool had no free connection within 5 s. Retryable.Check Postgres health and postgres.max_connections.
MPBX-PG-TENANT-DENIEDpermission_deniedRow-level security or a table privilege refused the statement (SQLSTATE 42501): a company transaction tried to write a row of another company, move a row to another company, or touch an install-wide table (install settings, the company list). Also raised when the login role may not switch to mpbx_tenant/mpbx_system.A bug or an attack in the calling code: company code must only use TenantTx repositories. If it appears at start-up, grant the roles: GRANT mpbx_tenant, mpbx_system TO <login role>; (as a superuser).
MPBX-PG-QUERYinternalAny other database error. The message carries the SQLSTATE.Report it with the log line.
MPBX-PG-URL-INVALIDconfigpostgres.url does not parse as a postgres:// URL. The URL itself is never printed.Fix MPBX__POSTGRES__URL or mpbx.toml.
MPBX-PG-LOGIN-SCOPE-UNSAFEconfigAt start-up, a per-scope login (postgres.tenant_url / postgres.system_url, FU-PBX10-M1) has more rights than its scope allows: the tenant login is a superuser, has BYPASSRLS, is a member of mpbx_system or not of mpbx_tenant; or the system login is a superuser, has BYPASSRLS or is not a member of mpbx_system.Use the roles mpbx_tenant_login / mpbx_system_login from the migrations unchanged (docs/guides/database-logins.md).
MPBX-PG-MIGRATION-FAILEDinternalA migration failed and its transaction was rolled back; the schema is unchanged.Read the cause in the log, fix the database state or report a bug.
MPBX-PG-MIGRATION-MODIFIEDconfigA migration that is already applied was edited after release (checksum differs). Migrations are append-only.Ship the change as a new migration and restore the original file.
MPBX-PG-SCHEMA-AHEADconfigThe database has migrations this binary does not know: an older binary was started against a newer schema. Nothing is changed.Run the newer release, or roll back with the pre-upgrade database snapshot (mpbx rollback).
MPBX-PG-MIGRATION-DIRTYinternalA previous run stopped half way through a non-transactional migration.Restore from backup. (All shipped migrations are transactional, so this should not happen.)

ClickHouse (mpbx_storage::ch, W1-PBX-03)​

Messages never contain the server URL, credentials or row values.

CodeKindMeaningWhat to do
MPBX-CH-UNAVAILABLEunavailableClickHouse is unreachable, restarting, overloaded, or an insert timed out. Retryable. The writer does not fail the caller: it spills the batch to Valkey (bus:ch_spill) and replays it when ClickHouse answers.Check ClickHouse health. Watch mpbx_ch_spill_backlog_batches; it returns to 0 after recovery.
MPBX-CH-QUERYinternalClickHouse rejected a query or insert for a reason other than availability. The message carries the server error number. A rejected insert is moved to the dead-letter stream bus:ch_dead (mpbx_ch_rows_dead_total) instead of blocking the spill queue.Inspect bus:ch_dead, fix the schema or the writer, report a bug.
MPBX-CH-CONFIGconfigclickhouse.url is missing or is not an http(s):// URL, or clickhouse.database is not letters, digits and underscores.Fix MPBX__CLICKHOUSE__URL / MPBX__CLICKHOUSE__DATABASE or mpbx.toml.
MPBX-CH-MIGRATION-FAILEDinternalA ClickHouse migration statement failed. ClickHouse has no transactional DDL, so earlier statements of the same migration may have been applied; all statements are idempotent, so run mpbx migrate --ch again after fixing the cause.Read the cause in the message, fix the server state, run again.
MPBX-CH-MIGRATION-MODIFIEDconfigAn already-applied ClickHouse migration file was edited (checksum differs).Ship the change as a new migration and restore the original file.
MPBX-CH-SCHEMA-AHEADconfigThe ClickHouse database has migrations this binary does not know: an older binary was started against a newer schema. Nothing is changed.Run the newer release.
MPBX-CH-WRITER-CLOSEDunavailableA row was written after the batched writer was closed (shutdown in progress).Not an operator problem; the process is stopping.

Valkey and ClickHouse (tenant isolation, W1-PBX-10)​

CodeKindMeaningWhat to do
MPBX-VALKEY-TENANT-KEYinternalA company-scoped Valkey handle (TenantValkey) was given a key outside the company's t:{tenant_id}: prefix (another company's key or an install-wide key). Nothing was read or written.A bug in the calling code: build keys with TenantValkey::keys().
MPBX-CH-TENANT-MISMATCHinvalid_argumentA ClickHouse row handed to a company's writer already names another company in tenant_id. The batch is refused.A bug in the calling code: never copy tenant_id from input; the writer sets it from the tenant context.