# ARX error codes (SQL Server)

Every error an ARX call throws is an `ArxException` with a stable `Code` (`ArxErrorCode`), the same in every provider (a misuse found while the schema catalog is built at startup, such as a table declared twice, is an `ArgumentException`). The message starts with it (`ARX3001 UniqueViolation: …`) and the thousands digit is its `Category`. Catch by code, on the base class: `catch (ArxException e) when (e.Code == ArxErrorCode.RecordNotFound)`. Some codes come as a subclass (`ArxValidationException` before the database, `ArxDatabaseException` from it, `ArxNotSupportedException` for ARX8001), but not every one: a record not found (ARX2002) can be the base class, so a catch of a subclass can miss it. Retry only when `IsTransient` is true. The database's own error stays on the exception: `NativeCode`, and the driver's exception as `InnerException`.

## ARX1xxx Validation

ARX refused the call before sending it: invalid input, a misused connection, transaction or batch scope, or a name that looks like SQL injection.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX1001 | `InvalidArgument` | Invalid input not covered by a more specific code. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1002 | `MissingEntityName` | The entity name is null or blank. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1003 | `InvalidIdentifier` | An entity or attribute name fails the identifier rules. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1004 | `DuplicateAttribute` | The same attribute appears more than once (names are case-insensitive). | no | no database error maps to it (ARX itself can still raise it) |
| ARX1005 | `InvalidLookup` | A lookup (`ArxEntityReference`) has no usable Id. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1006 | `InvalidSelectionSet` | A selection set value has no option set name. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1007 | `UnsupportedValueType` | An attribute value has a type the provider can't write. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1008 | `InvalidConnection` | The connection or transaction is of the wrong driver type, or the service has no connection string. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1009 | `TransactionMismatch` | The transaction belongs to a different connection. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1010 | `TransactionCompleted` | The transaction has already been committed, rolled back or disposed. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1011 | `SelectionSetValueNotAllowed` | A selection set value isn't allowed by its set in the catalog: not one of its options, of the wrong kind, a retired option, several values for a single-choice set, a duplicate, or a value the set's storage can't hold. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1012 | `UnknownSelectionSet` | A selection set value names a set that isn't in the catalog, or no catalog was supplied. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1013 | `InvalidDateTimeValue` | A date or time value that would be stored as something else than the caller meant: default(DateTime), default(DateTimeOffset) or default(DateOnly) (no real date: a database would store a sentinel or refuse it), or an array mixing UTC and Unspecified DateTime values. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1014 | `BatchScopeBusy` | A batch scope was called while another call on it was still running. A scope holds one connection, which runs one command at a time: await each call before the next. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1015 | `TransactionAborted` | A call or a commit on a transaction that an earlier failed call has aborted. The database has already discarded the transaction's work; it can only be rolled back. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1016 | `IdNotDeclared` | The entity's table isn't declared in the service's schema catalog, and the entity doesn't declare its own id column. A service with a catalog uses only what is declared: ARX doesn't guess an id column. A service created without a catalog reads the table's primary key instead (where the provider can), and raises `TableNotResolvable` when it can't. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1017 | `SuspectedInjection` | A name (entity, attribute, match column or type) contains SQL syntax: a quote, a statement separator, a comment marker, a bracket, an operator or an SQL keyword after a space. That is the shape of an SQL injection attempt, not of a typo, so it gets its own code to alert on. Refused before the database: nothing was sent. Values are never checked for this: they are always parameters, and any text is stored as typed. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1018 | `NotPreloaded` | The service is `Strict` and the call names a table or column that wasn't preloaded: refused before the database. Preload it, or turn Strict off. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1019 | `TableNotResolvable` | A service without a schema catalog resolves each table from the database, and this table has no id the call can use: no primary key, a primary key of several columns, or one of a type ARX can't use as an id. Refused before anything is sent, only for a call that needs the id (Create, Retrieve, Update or Delete by id). Declare the table in a schema catalog (`ArxIdColumn.NoIdColumn`), or match by a key or columns. | no | no database error maps to it (ARX itself can still raise it) |

## ARX2xxx NotFound

The rows the call addressed weren't found as asked: none, several where one was required, or one at another version than the call carried (ARX2004). Nothing was changed.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX2002 | `RecordNotFound` | The record addressed by key doesn't exist. | no | no database error maps to it (ARX itself can still raise it) |
| ARX2003 | `MultipleRecordsMatched` | An update or delete with `RequireSingleRow` found more than one row for an entity. Nothing was changed. | no | no database error maps to it (ARX itself can still raise it) |
| ARX2004 | `RecordChanged` | The record was changed since it was read: an Update or Delete carried a version (optimistic concurrency) that isn't the record's any more. Nothing was changed: read it again, and apply the change to what is there now. | no | no database error maps to it (ARX itself can still raise it) |

## ARX3xxx Constraint

The database refused the change because of a rule: a unique key, a foreign key, NOT NULL, CHECK, or a routine's own error.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX3001 | `UniqueViolation` | A unique constraint or key was violated. | no | `2601` duplicate key in a unique index; `2627` unique constraint violation |
| ARX3002 | `ForeignKeyViolation` | A referenced record is missing, or a record is still referenced. | no | `547` foreign key or check constraint conflict (told apart by the message) |
| ARX3003 | `NotNullViolation` | A required attribute has no value. | no | `515` NULL into a NOT NULL column |
| ARX3004 | `CheckViolation` | A check constraint or validation rule failed. | no | `547` check constraint conflict (the same number as a foreign key conflict; ARX reads which) |
| ARX3005 | `RaisedByDatabase` | A routine the database runs (a procedure or function) refused the call on purpose (PostgreSQL `RAISE EXCEPTION`, SQL Server `THROW`, MySQL `SIGNAL`). On PostgreSQL: `RAISE EXCEPTION` (SQLSTATE P0001), an `ASSERT` or a state of the routine's own (`USING ERRCODE = 'AX001'`). The message is the routine's; `SqlState`, `Detail` and `Hint` are its own. | no | `50000+` THROW or RAISERROR with your own message or number |

## ARX4xxx Data

A value doesn't fit its column: out of range, too long, in the wrong format or of the wrong type.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX4001 | `ValueOutOfRange` | A number is outside the column's range. | no | `220` arithmetic overflow for a small integer type; `232` arithmetic overflow for type; `242` date or time out of the type's range; `517` date arithmetic overflow; `8115` arithmetic overflow converting a value |
| ARX4002 | `ValueTooLong` | Text or binary data is longer than the column allows. | no | `2628` string or binary data would be truncated; `8152` string or binary data would be truncated (older form) |
| ARX4003 | `InvalidValueFormat` | A value can't be parsed for its column (for example invalid JSON, dates or encoding). | no | `235` a text value can't be converted to money; `241` date or time conversion failed; `245` conversion failed; `8114` error converting a parameter's data type; `8169` conversion to uniqueidentifier failed; `13609` JSON text isn't properly formatted |
| ARX4004 | `DataTypeMismatch` | A value's type doesn't fit the column. | no | `201` a procedure parameter wasn't supplied; `206` operand type clash; `257` implicit conversion not allowed; `402` data types incompatible in an operator; `8144` too many arguments for a procedure or function; `8145` a named argument the procedure doesn't have |

## ARX5xxx Schema

A table or column doesn't exist, or a declaration in the schema catalog doesn't match the table.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX5001 | `UndefinedEntity` | The table or collection doesn't exist. | no | `208` invalid object name; `2812` stored procedure not found |
| ARX5002 | `UndefinedAttribute` | The column doesn't exist or can't be written. | no | `207` invalid column name; `271` a computed column can't be modified; `544` a value into an IDENTITY column; `8101` an explicit value for an IDENTITY column; `8102` an identity column can't be updated; `8120` a column neither grouped nor aggregated |
| ARX5003 | `SchemaMismatch` | A declaration in the schema catalog doesn't match the table: the database returned an id of another type, or `ValidateSchemaAsync` found a difference. The exception says whether rows were stored. | no | no database error maps to it (ARX itself can still raise it) |

## ARX6xxx Permission

The database user isn't allowed to do it.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX6001 | `PermissionDenied` | The database user lacks the required permission. | no | `229` permission denied on an object; `230` permission denied on a column; `262` permission denied in the database; `18456` login failed; `33504` a row-level security block predicate refused the change |

## ARX7xxx Transient

A temporary failure: a deadlock, a conflict, a timeout, throttling or a lost connection. Safe to retry the whole operation (`IsTransient` is true).

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX7001 | `Deadlock` | The operation was chosen as a deadlock victim. Safe to retry. | yes | `1205` chosen as the deadlock victim |
| ARX7002 | `SerializationFailure` | The operation conflicted with a concurrent transaction. Safe to retry. | yes | `3960` snapshot isolation update conflict |
| ARX7003 | `Timeout` | The command or a lock wait timed out. Safe to retry. | yes | `-2` the command timed out (client); `1222` lock request timeout |
| ARX7004 | `Throttled` | The server is rate-limiting or out of connections. Safe to retry later. | yes | `10928` resource limit reached; `10929` too busy; `40501` the service is busy |
| ARX7005 | `ConnectionFailure` | The database couldn't be reached, or the connection dropped. Safe to retry. | yes | `2` the server can't be reached; `53` network path not found; `233` no process on the other end of the pipe; `4060` cannot open the database; `10053` the connection was aborted; `10054` the connection was reset; `10060` the connection timed out; `10061` the connection was refused; `40613` database not currently available; `severity 20+` a fatal error: the connection is closed |

## ARX8xxx NotSupported

The provider can't do what was asked, and refuses it rather than ignoring part of it.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX8001 | `NotSupported` | The provider doesn't support the requested operation or feature. | no | `102` incorrect syntax; `156` incorrect syntax near a keyword; `266` a procedure changed the transaction count (committed or rolled back the caller's transaction); `1934` the operation needs other SET options; `2809` a function called as a procedure (a table-valued function: EXEC refuses it); `3902` COMMIT with no matching BEGIN TRANSACTION; `3903` ROLLBACK with no matching BEGIN TRANSACTION; `4403` a view with DISTINCT, GROUP BY or aggregates can't be updated; `4405` a view's change would affect several base tables; `4406` a view's derived field can't be updated; `4413` a view or function can't be used; `7601` full-text search on a column without a full-text index |

## ARX9xxx Provider

A database error ARX doesn't map; the exception keeps its native code and SQLSTATE.

| Code | Name | Meaning | Safe to retry | From SQL Server |
|---|---|---|---|---|
| ARX9001 | `ProviderError` | A native error the provider doesn't map; see NativeCode and SqlState. | no | any other error number |

