Skip to content

Fall back to LIST when XLIST advertises but returns unusable data - #63

Open
monperrus wants to merge 1 commit into
jmapio:masterfrom
monperrus:fix-xlist-fallback
Open

Fall back to LIST when XLIST advertises but returns unusable data#63
monperrus wants to merge 1 commit into
jmapio:masterfrom
monperrus:fix-xlist-fallback

Conversation

@monperrus

Copy link
Copy Markdown

Bug

JMAP::Sync::Common::folders() crashes with:

Can't use string ("ok") as an ARRAY ref while "strict refs" in use
  at JMAP/Sync/Common.pm line 488

on a live Dovecot (poste.io) deployment that advertises the XLIST
capability in its CAPABILITY response but, when actually sent an
XLIST command, replies with just the tagged completion status
instead of well-formed folder tuples.

folders() picks the list command based purely on capability
advertisement:

my $listcmd = $imap->capability()->{xlist} ? 'xlist' : 'list';
my @folders = $imap->$listcmd('', '*');

Reproduced directly against the live server with Mail::IMAPTalk:

$imap->list('', '*')   # → 6 well-formed folder tuples, as expected
$imap->xlist('', '*')  # → ('ok')  -- just the completion status

Since @folders then contains a single non-ref string 'ok', the
foreach loop's @{$folder->[0]} dereference dies with the error
above, aborting account setup entirely (POST /api/accounts returns
201 with a "setup failed: ..." warning and the account never
syncs any folders/messages).

Fix

After calling the capability-selected command, detect a malformed
XLIST result (any non-arrayref element) and retry with the standard
LIST command, which is universally reliable. This only changes
behavior on the specific failure case — servers with working XLIST
are unaffected.

Testing

Verified end-to-end against the live deployment (poste.io mail server,
Dovecot backend) via the Docker image
(ghcr.io/jmapio/jmap-proxy:latest):

  • Before fix: POST /api/accounts201 with
    "warning":"setup failed: Can't use string (\"ok\") as an ARRAY ref...",
    account left with 0 folders / 0 messages.
  • After fix: POST /api/accounts → clean 201, account synced
    6 folders / 49 messages successfully.

Also confirmed this is not a general "second IMAP command on the
connection" issue — namespace() and plain list() both work
reliably on this server; only the generic xlist dispatch returns
unusable data.

Observed against a Dovecot (poste.io) deployment that advertises the
XLIST capability but replies to an XLIST command with just the tagged
completion status ("ok") instead of folder tuples — Mail::IMAPTalk's
generic command dispatch then hands folders() a single-element list
containing that string, and dereferencing $folder->[0] in the foreach
loop dies with "Can't use string ("ok") as an ARRAY ref".

Confirmed via direct testing: $imap->list('', '*') returns correctly
shaped data on the same connection where $imap->xlist('', '*') does
not, so this detects a malformed XLIST response and retries with the
standard LIST command instead of crashing account setup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant