Updating objects
The update command applies a JMAP patch to one object (or a singleton). The patch shape mirrors JMAP's Foo/set update argument: only the changed fields are sent.
Synopsis
stalwart-cli update <object> [<id>] ( --field key=value... | --json '<json>' | --file <path> | --stdin )
<object>: object type name (with or withoutx:prefix). The slash form is rejected here (it is acreatefeature).<id>: required for normal objects; optional for singletons (defaults tosingleton). Passing any non-singletonid for a singleton is rejected.- The four input forms are mutually exclusive.
Field paths and JSON pointers
For --field keys, two forms are supported:
- Top-level property name:
--field name=foosets the entire property. - JSON pointer path:
--field 'aliases/2/name=foo'patches a sub-element. The first segment is matched against the schema (case-insensitive, rewritten to canonical case). Deeper segments (map keys, list indices, nested object properties) are passed through verbatim.
This makes targeted edits cheap. For example, adding one entry to a set:
stalwart-cli update domain b --field 'aliases/extra.example.com=true'
And removing one entry from a set or map:
stalwart-cli update domain b --field 'aliases/extra.example.com=null'
The JSON pointer model is the same one JMAP uses internally:
- Sets are encoded as a map of
value -> true. Set the value totrueto add, tonullto remove. - Object lists are encoded as a map of stringified positional indices to objects. Use a new index to add, set the index to
nullto remove. - Maps are plain JSON objects: set a key's value to update, set it to
nullto delete.
Quoted keys
When a JSON-pointer path contains characters that would otherwise be misparsed (for example a literal = in a CIDR or header name), quote the entire key:
stalwart-cli update systemsettings --field '"proxyTrustedNetworks/127.0.0.1"=true'
Without quotes, the parser splits on the first =, which would land inside the path. With quotes, everything between the matching quote characters is the key, and the first = after the closing quote separates key from value.
Updating singletons
Singletons accept (or default to) the literal id singleton:
stalwart-cli update systemsettings --field allowRelaying=true
stalwart-cli update systemsettings singleton --field allowRelaying=true
Both are equivalent. Passing any other id for a singleton is rejected with a clear error.
Input sources
Identical to create:
| Source | When to use |
|---|---|
--field key=value | Quick targeted edits from the shell |
--json '<json>' | A small structured patch composed inline |
--file <path> | A patch generated by another tool or template |
--stdin | A patch piped from another command |
For the JSON forms, the document is the patch object sent to JMAP, not the full object. Setting a sub-key with the JSON forms uses the JSON-pointer convention (the keys may contain /):
stalwart-cli update domain b --json '{"description": "Renamed", "aliases/extra.example.com": true}'
Repeating the same key with --field is an error. Mixing input sources is also an error (only one may be supplied).
Examples
Change a description:
stalwart-cli update domain b --field description='Primary domain'
Toggle a singleton flag:
stalwart-cli update systemsettings --field allowRelaying=false
Replace a structured field:
stalwart-cli update domain b \
--field 'certificateManagement={"@type":"Automatic","acmeProviderId":"a"}'
Add a new alias to an object list (next available index):
stalwart-cli update account/user b --field 'aliases/3={"name":"hello","domainId":"b"}'
Add an item to a set (using set-of-id semantics):
stalwart-cli update account/user b --field 'memberGroupIds/g1=true'
Remove the same item:
stalwart-cli update account/user b --field 'memberGroupIds/g1=null'
Apply a patch generated by another tool:
generate-domain-patch.sh | stalwart-cli update domain b --stdin
Variant changes
For multi-variant objects, changing the variant requires patching the entire sub-object atomically (JMAP cannot mix @type/... JSON pointer keys with sibling property changes when the type itself changes). Send the new variant's full body in one go:
stalwart-cli update domain b \
--field 'certificateManagement={"@type":"Automatic","acmeProviderId":"a"}'
The CLI does not validate variant changes (the server does). For complex variant transitions, prefer a JSON file built by a configuration tool.
Output
A success line is printed:
Updated Domain b
If the server returns server-set fields after the update (rare; mostly for fields that are recomputed), they are rendered below in the same form-driven view as get.
See also
- Fetching a single object to verify changes.
- Creating objects for the corresponding create flow.
- Declarative bulk operations for atomic multi-object updates with cross-references.