Skip to content

MailboxSet and EmailSet responses causing KeyError: 'updated' #120

@rwood-moz

Description

@rwood-moz

Hi, I keep seeing a KeyError: 'updated' when attempting to create or update a mailbox via MailboxSet. The actual mailbox is being created successfully however there is an error in jmapc processing the MailboxSetResponse. I am having the same issue with EmailSet also. I am using the latest "jmapc==0.2.23". My python code for MailboxSet:

mailbox_name = "My new mailbox"

method = [
    MailboxSet(
        create=dict(new_mailbox=Mailbox(
            name=mailbox_name,
            is_subscribed=True,
        ),
    )),
]

# call JMAP API with the method
log.debug(f'creating mailbox: {mailbox_name}')
result = self.client.request(method)

Causes this error stack:

DEBUG    creating mailbox: AutoTest 2025-07-08 15:04:27.594391
DEBUG    Sending JMAP request {"methodCalls": [["Mailbox/set", {"accountId": "f", "create": {"new_mailbox": {"name": "AutoTest 2025-07-08 15:04:27.594391", "sortOrder": 0, "isSubscribed": true}}, "onDestroyRemoveEmails": false}, "single.Mailbox/set"]], "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"]}
DEBUG    urllib3.connectionpool:connectionpool.py:544 <URL> "POST /jmap/ HTTP/1.1" 200 179
DEBUG    jmapc:client.py:285 Received JMAP response {"methodResponses":[["Mailbox/set",{"accountId":"f","oldState":"sxquq","newState":"sxuuq","created":{"new_mailbox":{"id":"bpi"}}},"single.Mailbox/set"]],"sessionState":"3e25b2a0"}
======================================================================================= short test summary info ========================================================================================
FAILED jmap/test_jmap_mailboxes.py::TestJMAPMailboxes::test_create_mailbox - KeyError: 'updated'

../common/JMAP.py:188: in create_mailbox
    result = self.client.request(method)
../../.venv/lib/python3.13/site-packages/jmapc/client.py:249: in request
    ] = self._api_request(api_request)
../../.venv/lib/python3.13/site-packages/jmapc/client.py:286: in _api_request
    api_response = APIResponse.from_dict(r.json())
../../.venv/lib/python3.13/site-packages/dataclasses_json/api.py:70: in from_dict
    return _decode_dataclass(cls, kvs, infer_missing)
../../.venv/lib/python3.13/site-packages/dataclasses_json/core.py:202: in _decode_dataclass
    init_kwargs[field.name] = overrides[field.name].decoder(
../../.venv/lib/python3.13/site-packages/jmapc/api.py:38: in decode_method_responses
    response=_response_type(name).from_dict(response),
../../.venv/lib/python3.13/site-packages/dataclasses_json/api.py:70: in from_dict
    return _decode_dataclass(cls, kvs, infer_missing)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'jmapc.methods.mailbox.MailboxSetResponse'>, kvs = {'account_id': 'f', 'created': {'new_mailbox': {'id': 'bpi'}}, 'new_state': 'sxuuq', 'not_created': None, ...}, infer_missing = False

    def _decode_dataclass(cls, kvs, infer_missing):
        if _isinstance_safe(kvs, cls):
            return kvs
        overrides = _user_overrides_or_exts(cls)
        kvs = {} if kvs is None and infer_missing else kvs
        field_names = [field.name for field in fields(cls)]
        decode_names = _decode_letter_case_overrides(field_names, overrides)
        kvs = {decode_names.get(k, k): v for k, v in kvs.items()}
        missing_fields = {field for field in fields(cls) if field.name not in kvs}
    
        for field in missing_fields:
            if field.default is not MISSING:
                kvs[field.name] = field.default
            elif field.default_factory is not MISSING:
                kvs[field.name] = field.default_factory()
            elif infer_missing:
                kvs[field.name] = None
    
        # Perform undefined parameter action
        kvs = _handle_undefined_parameters_safe(cls, kvs, usage="from")
    
        init_kwargs = {}
        types = get_type_hints(cls)
        for field in fields(cls):
            # The field should be skipped from being added
            # to init_kwargs as it's not intended as a constructor argument.
            if not field.init:
                continue
    
>           field_value = kvs[field.name]
E           KeyError: 'updated'

../../.venv/lib/python3.13/site-packages/dataclasses_json/core.py:168: KeyError

Any help would greatly be appreciated :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions