Console v0.9.365. "Import repeater contacts" ("Seed with contacts from the repeater's adverts. Results are ordered by most recent first.") fetches the preview and never performs the import. The contacts appear in the UI, and are gone on the next page load, because nothing was ever written.
Evidence
I instrumented the repeater (a before_handler CherryPy tool logging every request, plus a hook on the companion frame server's command dispatch) and clicked the button. The complete set of requests it makes:
GET /api/adverts_by_contact_type?contact_type=Room+Server
GET /api/adverts_by_contact_type?contact_type=Chat+Node
GET /api/adverts_by_contact_type?contact_type=Repeater
Three GETs, then nothing. Specifically, over several attempts:
noPOST /api/companion/import_repeater_contacts — the endpoint that implements this feature, whose docstring matches the button's own description ("Import repeater adverts into this companion's contact store (one-time seed). Results are sorted by last_seen DESC.")
no POST/PUT/PATCH/DELETE of any kind
noCMD_ADD_UPDATE_CONTACT / CMD_IMPORT_CONTACT / CMD_REMOVE_CONTACT over the companion frame transport (instrumented at the dispatcher; zero received)
no change to companion_contacts in SQLite — the target companion stayed at 114 rows across every attempt
The UI displayed all 285 adverts each time, so the preview itself works; only the write is missing.
Expected
After the preview, POST the selection to /api/companion/import_repeater_contacts with {companion_name, contact_types?, hours?, limit?} and report imported / removed from the response.
Note for whoever picks this up
That endpoint has its own bug which will bite as soon as the Console starts calling it: it compares the API's type names (repeater, companion, room_server, sensor) against the display names stored in adverts.contact_type (Repeater, Chat Node, Room Server, Sensor), so any request carrying contact_types imports zero rows. Reported and fixed at openhop-dev/openhop_repeater#435 / #436. If the Console sends type filters — and its UI implies it will — both fixes are needed for this feature to work.
### Summary
**Console v0.9.365.** "Import repeater contacts" ("Seed <companion> with contacts from the repeater's adverts. Results are ordered by most recent first.") fetches the preview and never performs the import. The contacts appear in the UI, and are gone on the next page load, because nothing was ever written.
### Evidence
I instrumented the repeater (a `before_handler` CherryPy tool logging every request, plus a hook on the companion frame server's command dispatch) and clicked the button. The complete set of requests it makes:
```
GET /api/adverts_by_contact_type?contact_type=Room+Server
GET /api/adverts_by_contact_type?contact_type=Chat+Node
GET /api/adverts_by_contact_type?contact_type=Repeater
```
Three GETs, then nothing. Specifically, over several attempts:
- **no** `POST /api/companion/import_repeater_contacts` — the endpoint that implements this feature, whose docstring matches the button's own description ("Import repeater adverts into this companion's contact store (one-time seed). Results are sorted by last_seen DESC.")
- **no** POST/PUT/PATCH/DELETE of any kind
- **no** `CMD_ADD_UPDATE_CONTACT` / `CMD_IMPORT_CONTACT` / `CMD_REMOVE_CONTACT` over the companion frame transport (instrumented at the dispatcher; zero received)
- **no** change to `companion_contacts` in SQLite — the target companion stayed at 114 rows across every attempt
The UI displayed all 285 adverts each time, so the preview itself works; only the write is missing.
### Expected
After the preview, POST the selection to `/api/companion/import_repeater_contacts` with `{companion_name, contact_types?, hours?, limit?}` and report `imported` / `removed` from the response.
### Note for whoever picks this up
That endpoint has its own bug which will bite as soon as the Console starts calling it: it compares the API's type names (`repeater`, `companion`, `room_server`, `sensor`) against the display names stored in `adverts.contact_type` (`Repeater`, `Chat Node`, `Room Server`, `Sensor`), so **any** request carrying `contact_types` imports zero rows. Reported and fixed at openhop-dev/openhop_repeater#435 / #436. If the Console sends type filters — and its UI implies it will — both fixes are needed for this feature to work.
### Environment
Console v0.9.365, openHop Repeater 0.1.dev1191, openhop_core 1.1.3.dev25, Raspberry Pi 4, Python 3.13.5.
<!-- github-sync-id:5338358748 -->
Re-tested after upgrading 0.9.365 → 0.9.368 (hard-refreshed to clear the cached bundle). Same result: the preview renders the full advert list, and the target companion's companion_contacts row count is unchanged — measured before and after with
All four companions: +0. Most recent write predates the click.
Worth recording because 0.9.366 reworked the companion/messages page including the roster's Import key, so it was a reasonable candidate to have fixed this incidentally. It did not — the behaviour is identical across 0.9.365 and 0.9.368, which suggests the missing call is not in the part that was rewritten.
The repeater side is healthy and current in this test (openhop_core 1.1.3.dev25, openhop_repeater 0.1.dev1192, both at upstream dev HEAD), and POST /api/companion/import_repeater_contacts works correctly when called directly — a manual call against the same companion returned {"success": true, "data": {"imported": 285, "removed": 0}} and the rows persisted. So the endpoint and the database path are fine; only the Console's request is missing.
Still present on **0.9.368**.
Re-tested after upgrading 0.9.365 → 0.9.368 (hard-refreshed to clear the cached bundle). Same result: the preview renders the full advert list, and the target companion's `companion_contacts` row count is unchanged — measured before and after with
```sql
SELECT companion_hash, COUNT(*), MAX(updated_at) FROM companion_contacts GROUP BY 1;
```
All four companions: **+0**. Most recent write predates the click.
Worth recording because 0.9.366 reworked the companion/messages page including the roster's Import key, so it was a reasonable candidate to have fixed this incidentally. It did not — the behaviour is identical across 0.9.365 and 0.9.368, which suggests the missing call is not in the part that was rewritten.
The repeater side is healthy and current in this test (openhop_core `1.1.3.dev25`, openhop_repeater `0.1.dev1192`, both at upstream `dev` HEAD), and `POST /api/companion/import_repeater_contacts` works correctly when called directly — a manual call against the same companion returned `{"success": true, "data": {"imported": 285, "removed": 0}}` and the rows persisted. So the endpoint and the database path are fine; only the Console's request is missing.
<!-- github-comment-id:5530002073 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Console v0.9.365. "Import repeater contacts" ("Seed with contacts from the repeater's adverts. Results are ordered by most recent first.") fetches the preview and never performs the import. The contacts appear in the UI, and are gone on the next page load, because nothing was ever written.
Evidence
I instrumented the repeater (a
before_handlerCherryPy tool logging every request, plus a hook on the companion frame server's command dispatch) and clicked the button. The complete set of requests it makes:Three GETs, then nothing. Specifically, over several attempts:
POST /api/companion/import_repeater_contacts— the endpoint that implements this feature, whose docstring matches the button's own description ("Import repeater adverts into this companion's contact store (one-time seed). Results are sorted by last_seen DESC.")CMD_ADD_UPDATE_CONTACT/CMD_IMPORT_CONTACT/CMD_REMOVE_CONTACTover the companion frame transport (instrumented at the dispatcher; zero received)companion_contactsin SQLite — the target companion stayed at 114 rows across every attemptThe UI displayed all 285 adverts each time, so the preview itself works; only the write is missing.
Expected
After the preview, POST the selection to
/api/companion/import_repeater_contactswith{companion_name, contact_types?, hours?, limit?}and reportimported/removedfrom the response.Note for whoever picks this up
That endpoint has its own bug which will bite as soon as the Console starts calling it: it compares the API's type names (
repeater,companion,room_server,sensor) against the display names stored inadverts.contact_type(Repeater,Chat Node,Room Server,Sensor), so any request carryingcontact_typesimports zero rows. Reported and fixed at openhop-dev/openhop_repeater#435 / #436. If the Console sends type filters — and its UI implies it will — both fixes are needed for this feature to work.Environment
Console v0.9.365, openHop Repeater 0.1.dev1191, openhop_core 1.1.3.dev25, Raspberry Pi 4, Python 3.13.5.
Still present on 0.9.368.
Re-tested after upgrading 0.9.365 → 0.9.368 (hard-refreshed to clear the cached bundle). Same result: the preview renders the full advert list, and the target companion's
companion_contactsrow count is unchanged — measured before and after withAll four companions: +0. Most recent write predates the click.
Worth recording because 0.9.366 reworked the companion/messages page including the roster's Import key, so it was a reasonable candidate to have fixed this incidentally. It did not — the behaviour is identical across 0.9.365 and 0.9.368, which suggests the missing call is not in the part that was rewritten.
The repeater side is healthy and current in this test (openhop_core
1.1.3.dev25, openhop_repeater0.1.dev1192, both at upstreamdevHEAD), andPOST /api/companion/import_repeater_contactsworks correctly when called directly — a manual call against the same companion returned{"success": true, "data": {"imported": 285, "removed": 0}}and the rows persisted. So the endpoint and the database path are fine; only the Console's request is missing.