element-hq / element-hq/synapse

Cannot add Avatar to Application Service

Open
#19,702 5 comments 1 reaction 0 assignees View on GitHub
A-Application-Service A-Profiles
Dominant language
Python
Stars
4.6k
Forks
600
Avg merge
5d 22h
Merged PRs (30d)
51

Description

### Description

Calling `PUT /_matrix/client/v3/profile/{userId}/avatar_url?user_id={userId}` with an appservice token for a virtual user that has no existing profile row causes Synapse to crash with

```
TypeError: 'NoneType' object is not subscriptable` in `_check_profile_size
```

The upload step succeeds; only the profile `PUT` fails.

### Steps to reproduce

1. Register an application service via `app_service_config_files` in `homeserver.yml`
2. User can send "Hello, world!" to private room on synapse
3. Upload picture with `POST /_matrix/media/v3/upload?filename=&user_id=@:`
4. Call `PUT /_matrix/client/v3/profile/@:/avatar_url?user_id=@:` with the AS token
5. Synapse returns HTTP 500

### Homeserver

private homeserver

### Synapse Version

v1.151.0

### Installation Method

Docker (matrixdotorg/synapse)

### Database

PostgreSQL 18.1, single server, no SQLite migration

### Workers

Single process

### Platform

Ubuntu 24.04 (based on kernel 6.8), running in Docker container

### Configuration

_No response_

### Relevant log output

```shell
admin@my-homeserver:~$ docker logs matrix-synapse 2>&1 | grep -A20 "TypeError\|_check_profile_size\|ProfileField"
2026-04-16 20:24:50,818 - synapse.http.server - 147 - ERROR - PUT-21527 - Failed handle request via 'ProfileFieldRestServlet':
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/synapse/http/server.py", line 335, in _async_render_wrapper
callback_return = await self._async_render(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/synapse/http/server.py", line 576, in _async_render
callback_return = await raw_callback_return
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/synapse/rest/client/profile.py", line 212, in on_PUT
await self.profile_handler.set_avatar_url(
user, requester, new_value, by_admin=is_admin, propagate=propagate
)
File "/usr/local/lib/python3.13/site-packages/synapse/handlers/profile.py", line 364, in set_avatar_url
await self.store.set_profile_avatar_url(target_user, avatar_url_to_set)
File "/usr/local/lib/python3.13/site-packages/synapse/storage/databases/main/profile.py", line 435, in set_profile_avatar_url
await self.db_pool.runInteraction(
"set_profile_avatar_url", set_profile_avatar_url
)
File "/usr/local/lib/python3.13/site-packages/synapse/storage/database.py", line 1015, in runInteraction
return await delay_cancellation(_runInteraction())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
self._check_profile_size(
~~~~~~~~~~~~~~~~~~~~~~~~^
txn, user_id, ProfileFields.AVATAR_URL, new_avatar_url
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/local/lib/python3.13/site-packages/synapse/storage/databases/main/profile.py", line 354, in _check_profile_size
(row[0] - 1 if row[0] else 0)
~~~^^^
TyError: 'NoneType' object is not subscriptable
```

### Anything else that would be useful to know?

_No response_

Contributor guide

Open the contributing guide

Research direction

Start in synapse/storage/databases/main/profile.py at _check_profile_size and set_profile_avatar_url, following the call from handlers/profile.py and rest/client/profile.py. Reproduce the application-service avatar PUT with a virtual user lacking a profile row, then verify the request no longer returns HTTP 500 and the avatar URL is stored successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.