#23283·clients

`bw serve` returns an empty item list with `success: true` right after a sync

Author: NavidSassanCreated Sep 18, 2026Updated Sep 18, 2026
Labelsbugcli

Steps To Reproduce

  1. Log in and unlock a vault that contains at least one item, then start the API: bw serve --hostname 127.0.0.1 --port 8087

  2. Run a forced sync followed by a list, one request after the other:

    bash
    for i in $(seq 1 10); do
        curl --silent --request POST 'http://127.0.0.1:8087/sync?force=true' > /dev/null
        printf 'round %2d: ' "$i"
        curl --silent http://127.0.0.1:8087/list/object/items | jq --compact-output '[.success, (.data.data | length)]'
        sleep 2
    done
  3. The same with 8 clients in parallel makes it far more likely:

    bash
    for round in $(seq 1 5); do
        printf 'round %d: ' "$round"
        for i in $(seq 1 8); do
            (
                curl --silent --request POST 'http://127.0.0.1:8087/sync?force=true' > /dev/null
                curl --silent http://127.0.0.1:8087/list/object/items | jq '.data.data | length'
            ) &
        done | tr '\n' ' '
        wait
        echo
        sleep 5
    done

?force=true only makes every sync a full sync. Without it the same happens whenever the vault changed on the server since the last sync, which in an organization vault shared with others is the normal case.

Expected Result

Every GET /list/object/items returns all items of the vault. If the list cannot be served, the response should fail instead of reporting success: true.

Actual Result

Some responses report success: true with an empty list, although the vault contains the item. A few seconds later the same request returns the item again.

Output with a vault containing exactly one item (bw 2026.9.0, official Bitwarden cloud server):

### serial
round  1: [true,1]
...
round  9: [true,1]
round 10: [true,0]

### parallel
round 1: 1 0 1 1 1 1 1 1
round 2: 0 0 1 1 1 1 1 1
round 3: 1 0 1 1 1 1 1 1
round 4: 1 1 1 0 1 1 1 1
round 5: 1 1 1 1 1 1 1 1

1 of 10 serial and 5 of 40 parallel responses were empty. In the same window, GET /object/item/<id> for the existing item answered 400 Bad Request. Earlier runs with 2026.8.0 showed the same (13 of 80 empty responses with 8 parallel clients and forced syncs, 4 of 80 without force).

Screenshots or Videos

No response

Additional Context

Impact: automation that treats "not in the list" as "does not exist" creates the item again. We hit this with an Ansible lookup plugin that creates a missing login item through bw serve: it produced duplicates of items that had existed for months, and the next run then failed on the ambiguous match.

Operating System

Linux

Operating System Version

Rocky Linux 9.8 (container)

Shell

Bash

Build Version

2026.9.0 (also reproduced with 2026.8.0)

Issue Tracking Info

  • I understand that work is tracked outside of GitHub. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.