> For the complete documentation index, see [llms.txt](https://codemash.gitbook.io/codemash/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codemash.gitbook.io/codemash/cloud/database/schema/field-types/user-reference.md).

# User reference

A reference to one or several project users: the record stores the user id, the form and the list show a chosen user property.

A **User** reference points at a user of the project's Membership module. The record stores the **user id**; the schema's `displayField` says which user property Cloud shows instead — the e-mail, the full name, the company.

**Builder:** Form fields panel → **Select → Users** · widget `select` · data type `user.selection.schema.v1`

## Data schema

```json
{
  "assignee": {
    "source": "user",
    "displayField": "email",
    "multiple": false
  }
}
```

| Keyword        | Required | What it does                                                                                                           | Example   |
| -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | --------- |
| `source`       | yes      | Always `"user"`.                                                                                                       | `"user"`  |
| `displayField` | **yes**  | The user property shown for the id: `displayName`, `fullName`, `firstName`, `lastName`, `email`, `phone` or `company`. | `"email"` |
| `multiple`     | no       | `true` = the record stores an array of user ids.                                                                       | `true`    |

### What the server refuses

Every write — insert, update, replace; from Cloud, the API, an SDK, the CLI or an AI agent — is checked against the published schema. A broken value is answered with one error per field: the code, and `Field '<name>' is invalid: <reason>`. Nothing is written.

| Case                                    | Code                     | The reason it gives                                                             |
| --------------------------------------- | ------------------------ | ------------------------------------------------------------------------------- |
| a required field is missing or `null`   | `CM-ERRORS-DATABASE-030` | `a value is required`                                                           |
| an id that is not a user of the project | `CM-ERRORS-DATABASE-050` | `'usr_…' is not a user of this project`                                         |
| an array sent to a single reference     | `CM-ERRORS-DATABASE-039` | `must be a single reference (string), not an array — the field is not multiple` |
| a string sent to a multiple reference   | `CM-ERRORS-DATABASE-039` | `must be an array of references, not a single string — the field is multiple`   |
| an empty id                             | `CM-ERRORS-DATABASE-039` | `a reference id cannot be empty`                                                |
| the same id twice                       | `CM-ERRORS-DATABASE-046` | `entries must be unique — repeated: '…'`                                        |

A keyword that is not in the table above is refused when the schema is **saved**, not when a record is written: `CM-ERRORS-SCHEMA-010` — `Data schema violates meta-schema: Property 'sort' has not been defined and the schema does not allow additional properties. Path 'properties.assignee.sort' (field 'properties.assignee' checked as user.selection.schema.v1).`

## UI schema

The cell uses the `select` widget; the form opens a user picker that searches by the display field. A multiple reference shows the chosen users as chips.

```json
{
  "colSpan": 6,
  "element": {
    "fieldId": "assignee",
    "meta": { "widget": "select", "label": "Assignee" }
  }
}
```

Every cell also takes the common layout options: `label`, `placeholder`, `help` (the text under the input), `required`, `readonly` and `hidden`. Keys outside this list — `watermark`, `hint`, `permissions` — are refused when the schema is saved (`CM-ERRORS-SCHEMA-012`), see [Schema authoring guide](/codemash/cloud/database/schema.md#one-contract-no-second-dialect).

<figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-46d8cbe8a9366a60ca53ed13fb664e8ce88af82c%2Freferences-form-1.png?alt=media" alt="Edit Record form of sc_refs-cloud_tasks: Person shows Ada from a collection picker, People shows 2 items selected with the chips Ada and Grace, Assignee shows Ada from a user picker, Assignees shows the chips Ada and Grace, Topic shows Urgent, Topics shows Urgent and Later, Role shows Admin Portal Manager"><figcaption><p>Reference pickers on a record form: single values and multiple values as chips, each shown by its display field.</p></figcaption></figure>

## Records

A record the schema accepts:

```json
{ "assignee": "usr_3Kd9mQ2vLp8nR1tY6wXz4A" }
```

A record it refuses:

```json
{ "assignee": "usr_doesNotExist000000000" }
```

The answer: `CM-ERRORS-DATABASE-050` — `Field 'assignee' is invalid: 'usr_doesNotExist000000000' is not a user of this project`. In Cloud the same sentence is shown under the field before the form is sent; the server repeats the check on every API write.

## Good to know

* Existence is checked in the request's project on every write; a user deleted later leaves the id on the record and `expandReferences` answers `display: null` for it.
* Reading with `expandReferences: true` needs read permission on the project's users; otherwise the read is refused with `CM-ERRORS-DATABASE-056` — see [References](/codemash/cloud/database/schema/references.md).
* The record's **owner** (schema setting *Records have an owner*) is `_meta.responsibleUserId`, set by the server — not a user reference field.

## Do it from code

```ts
await norbix.api.database.insertOne({
  collectionName: 'tasks',
  document: JSON.stringify({ assignee: 'usr_3Kd9mQ2vLp8nR1tY6wXz4A' }),
});
```

```sh
norbix api database one insert --collectionName tasks --document '{"assignee":"usr_3Kd9mQ2vLp8nR1tY6wXz4A"}'
```

The client setup is on the [Database page](/codemash/cloud/database.md#use-it-from-code). API: [Insert One](/codemash/api-reference/database/collections/insert-one.md) · [Save Database Schema](/codemash/api-reference/database/schemas/save-database-schema.md)

## Related

[References](/codemash/cloud/database/schema/references.md) · [Role reference](/codemash/cloud/database/schema/field-types/role-reference.md) · [Users](/codemash/cloud/membership/users.md) · [Field type reference](/codemash/cloud/database/schema/field-types.md) · [Schema authoring guide](/codemash/cloud/database/schema.md) · [Create a schema](/codemash/cloud/database/collections/create-schema.md)
