Stalwart-cli does not support commands in the migration document

Issue Description

While following the Dovecot/Postfix migration guide, I encountered multiple inconsistencies between the published documentation and the currently released Stalwart Server (0.16.8) and stalwart-cli (1.0.8).

The migration guide states that accounts can be created using a full email address:

stalwart-cli create Account/User
–field name=alice@example .org
–field description=“Alice”

and that password hashes can be imported using:

stalwart-cli update Account alice@example .org
–field ‘secret=$6$rounds=5000$…’

However, the released versions do not appear to behave as documented.

Additionally, the CLI documentation indicates objects can be referenced by name:

stalwart-cli get Domain example .org

but the released CLI only appears to accept internal object IDs.

Expected Behavior

Account Creation

The migration guide suggests the following should work:

stalwart-cli create Account/User
–field name=alice@example .org
–field description=“Alice”
Password Import

The migration guide suggests:

stalwart-cli update Account alice@example .org
–field ‘secret=’

should update the account password hash.

Object Lookup

The documentation states:

stalwart-cli get Domain example .org

should retrieve the domain object by name.

Actual Behavior

Password Import
stalwart-cli update Account alice@example .org
–field ‘secret=’

returns:

error: unknown field: secret
Domain Lookup
stalwart-cli get Domain example .org

returns:

error: Domain example .org not found

However:

stalwart-cli query Account

returns:

Id Email Address Description
c alice@example .org Alice

and:

stalwart-cli get Domain c

returns:

Domain
Domain Name: example .org
Aliases:
Enabled: Yes

which suggests the CLI is expecting internal object IDs rather than names.

Account Creation

The account eventually appears in:

stalwart-cli query Account

but earlier attempts produced:

error: invalidPatch
Invalid email local part
Properties: name

making it unclear whether the migration guide examples are valid for the currently released versions.

Stalwart Version

v0.16.x

Installation Method

Binary (Linux)

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

Additional Context

The migration guide was published approximately 3 days ago.

The currently available versions appear to be:

Stalwart CLI 1.0.8 (released ~2 weeks ago)
Stalwart Server 0.16.8 (released ~1 week ago)

This suggests the migration documentation may describe functionality that has not yet reached the released server/CLI, or there may be undocumented differences in the expected syntax.

The accounts above have been renamed to not show live data/domains and the “Alice” account was created in the Web GUI to attempt setting it up.

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

Let me look into the current CLI documentation and migration guide to understand what’s expected.

Now I have a clear picture. Let me check how the secret field / credentials work for the Account object, since the user got error: unknown field: secret:

Now I have a very clear picture. Let me check the Account object schema to confirm the name vs name@domain issue and the correct credentials structure:

Now I have a clear picture. Let me also check the credentials field update syntax for password import:

Now I have a clear picture. Let me synthesize the findings for the user.

The migration guide’s documented CLI commands are accurate for the current CLI, but Andrew has been using the wrong field names for account creation and password import. Here is what the current docs actually say:


There are real inconsistencies between the migration guide’s examples and how the current CLI actually works, but some of these are also usage errors. Here is a breakdown of each issue:


1. Account creation: name must be the local part, not a full email address

The name field on an Account/User object has type EmailLocalPart (the docs confirm: “Name of the account, typically an email address local part”). Passing a full email address like [email protected] into --field [email protected] is what triggers:

error: invalidPatch — Invalid email local part

The @ character is not a valid local part character. The domain part is supplied separately via domainId. The correct creation command is:

# First, find your domain's internal ID:
stalwart-cli query Domain --where name=example.org --fields id

# Then create the account using the local part + domain ID:
stalwart-cli create Account/User \
  --field name=alice \
  --field domainId=<id-from-above> \
  --field description="Alice"

The migration guide’s example --field [email protected] appears to be incorrect or refers to a syntax that the current server does not accept. The full email address ([email protected]) is a server-set computed field (emailAddress), not something you set directly.


2. Password import: secret is not a top-level field; use credentials

There is no top-level secret field on the Account object, which is why --field 'secret=...' gives error: unknown field: secret. Credentials are stored in a structured credentials list. To set (or update) a password hash at creation time:

stalwart-cli create Account/User \
  --field name=alice \
  --field domainId=<id> \
  --field description="Alice" \
  --field 'credentials={"0":{"@type":"Password","secret":"$6$rounds=5000$..."}}'

To update credentials on an existing account by its internal ID:

stalwart-cli update Account <internal-id> \
  --field 'credentials/0={"@type":"Password","secret":"$6$rounds=5000$..."}'

Stalwart does recognise common crypt prefixes like $6$, $2, $argon2, etc., and stores them verbatim (as the migration guide correctly states), but the field path must be credentials, not secret.


3. get Domain <name> does not work; get requires an internal ID

This is confirmed by the current get documentation: <id> is the internal object ID, not a human-readable name. The get command does not accept names.

The correct workflow to look up a domain by name is:

stalwart-cli query Domain --where name=example.org --fields id

That returns the internal ID (e.g., b), which you then pass to get:

stalwart-cli get Domain b

The migration guide’s stalwart-cli get Domain example.org syntax is inaccurate for the current CLI. The guide does use query ... --where name=... for domain ID lookups in some places, which is the correct approach.


4. Invalidate caches after creating an account

The migration guide also notes an important step that is easy to miss: after creating an account, you must invalidate caches or the new account may fail to authenticate due to a stale negative cache entry:

stalwart-cli create Action --json '{"@type":"InvalidateCaches"}'

Relevant docs:

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

The docs have been fixed.