Engel’s notebook

Conversation list and folders

F04 · 41 mapped behaviors in the Self-Healing Codebase Project. Follow the prerequisites, actions and expected results; expand the original CLI recipe to replay it.

778 behavior IDs · 28 families · 844 named recipes & support steps
16 October 2026 · PR #18334 at 9a3c3a69
Canvas 1.27.1 · Agent Server 1.55.0 · automation 1.20.0

This is the map at the revision above, including its open bug notes. It does not incorporate later changes on main or claim a fresh verification run. Setup & reading guide · Download the scenario inventory

All scenarios & marker key · Open a script to read Given / Do / Expect. Expand the exact recipe for replayable commands.

F04 Conversation list and folders

41 behaviors · 43 scripts & contracts · Maintained source

Entry points & prerequisites

What this family covers

The expanded sidebar always shows the user's conversations under a Conversations header. Each row opens its conversation and carries a pin and a ⋮ menu (Rename, Edit tags, Stop, Download, Archive or Unarchive, Delete). The header has a folder-plus picker that starts a conversation in a chosen workspace and a View menu with layout presets, tag filters, More options (organize, sort, scope, archived, age cutoff, automation filter, row metadata) and Delete all. Grouped by workspace, folders collapse, preview five rows and start new conversations in place. Preferences, pins, archives and the workspace each conversation was started in live in this browser's localStorage.

How a user gets here

  • Always visible in the expanded sidebar on every page (/, the direct URL /conversations, /conversations/<id>, settings pages): the Conversations section under New Chat / Customize / Automate. At phone width it is inside the drawer opened by sidebar-mobile-menu-toggle.
  • Header: folder-plus (conversation-panel-new-thread-picker, aria "Create thread folder — choose workspace or repository"), View (conversation-layouts-toggle), and in grouped mode the Conversations label itself (conversations-header-toggle).
  • Row hover: pin (conversation-pin-toggle-<id>) and ⋮ (ellipsis-button, aria "More options"), which opens context-menu. A row with more tags than fit shows a +N chip (conversation-card-tag-overflow). The Pinned section has its own More/Less (conversation-panel-pinned-view-more).
  • View → More options (advanced-options-row) opens advanced-conversation-options-modal (Organize, Sort by, Threads scope-all/scope-relevant, Additional, Automations, Metadata).
  • Grouped mode: folder heading (thread-folder-drag-<suffix>), folder + (aria "Start new conversation in <folder>"), folder More/Less (thread-folder-view-more-<suffix>).
  • No command-menu entry or keyboard shortcut exists for the list.

Given

Preconditions:

  • Baseline state (launched, doctored, onboard --skip done), desktop viewport, deepseek-flash active for the one prompted conversation.
  • F04.empty-state and the disabled Delete all are first checked on a run with no conversations (a fresh launch --new), and again after F04.delete-all.
  • Workspaces: control-openhands fixture git-repo --name qa-f04-repo and control-openhands fixture folder --name qa-f04-folder, then add both through the picker (F03 owns the folder browser): control-openhands browser click 'testid=conversation-panel-new-thread-picker', control-openhands browser click 'testid=add-workspaces-button', control-openhands browser click 'testid=folder-browser-up' twice (from <run>/private/home to the run directory; check with browser text 'testid=folder-browser-current-path'), control-openhands browser dblclick 'testid=folder-browser-entry-workspace', control-openhands browser click 'testid=folder-browser-add-all-subdirs'. The picker popover stays open afterwards; control-openhands browser click 'testid=conversation-panel-new-thread-picker' closes it.
  • A finished conversation, started right after the View menu bullet (the first two bullets need a run with no conversations): control-openhands conversation start --prompt "Reply with only the word pong. Do not run any tools." --wait --timeout 240. The model writes the title (✅ Reply only with pong, ✅ Reply with pong only, ...): select its row with has-text=pong.
  • F04.load-more and F04.folder-preview-more need more than 20 conversations, at least 6 in one folder. Empty conversations from the folder + cost no model call (see F04.folder-new-conversation).
  • F04.cloud-picker and F04.start-task-cards are blocked: they need an OpenHands Cloud backend with a connected git provider. The kept rows of F04.automation-filter (Only automation runs with real runs) and the hiding effect of F04.hide-older need data a fresh run cannot have (an automation-run conversation; a conversation older than one hour).
Empty listF04.empty-stateMapped behavior

Scenario F04--empty-list · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    On a run with no conversations, run control-openhands browser text 'testid=conversation-panel-empty-state'. The text is No conversations found.

Expect

with no conversations (By date) the list shows No conversations found.

Exact CLI recipe & bug checks

On a run with no conversations, run control-openhands browser text 'testid=conversation-panel-empty-state'. The text is No conversations found.

View menuF04.view-menuMapped behavior

Scenario F04--view-menu · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversation layouts toggle”.
  2. Do
    Choose “Tag filters section”.
  3. Do
    Press Escape.

Expect

the View menu lists the presets By workspace, Recent, Active and Compact (a fresh profile has Recent checked), Filter by tags (No tags yet when empty), More options and Delete all (disabled with no conversations); Escape closes it.

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=conversation-layouts-toggle' and control-openhands browser snapshot 'testid=conversation-layouts-menu': radios By workspace, Recent ([checked]), Active, Compact, items Filter by tags, More options and Delete all (control-openhands browser attr 'testid=layout-preset-recent-activity' aria-checked is true). With no conversations control-openhands browser enabled 'testid=delete-all-conversations' is false; after control-openhands browser click 'testid=tag-filters-section', control-openhands browser text 'testid=tag-filters-empty' is No tags yet. control-openhands browser press Escape closes the menu (browser count 'testid=conversation-layouts-menu' is 0).

Start in a workspaceF04.new-thread-pickerKnown failure

Scenario F04--start-in-a-workspace · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Open /.
  2. Do
    Choose “Conversation panel new thread picker”.
  3. Do
    Choose “Conversation panel new thread popover” / “Launch workspace” / containing “qa-f04-repo”.
  4. Do
    Choose “Manage workspaces”.

Expect

the folder-plus button lists No workspace, every known workspace, + Add Workspace and Manage Workspaces; picking a row starts a conversation there and opens it.

Known bug observations

Known failure (reproduced 2026-10-12, #16752): this empty idle row retains active green styling instead of the expected neutral state; the older report's flashing animation was not observed.

Exact CLI recipe & bug checks

Run control-openhands browser goto /, control-openhands browser click 'testid=conversation-panel-new-thread-picker' and control-openhands browser snapshot 'testid=conversation-panel-new-thread-popover': buttons No workspace, qa-f04-folder, qa-f04-repo, + Add Workspace, Manage Workspaces. Then control-openhands browser click 'testid=conversation-panel-new-thread-popover >> testid=launch-workspace >> has-text=qa-f04-repo' --expect-url '/conversations/' returns /conversations/<id>, and control-openhands conversation list shows that id with workspace ending in /workspace/qa-f04-repo. From / again, testid=launch-no-workspace opens a new conversation whose row sits in the No workspace folder. control-openhands browser click 'testid=manage-workspaces-button' opens testid=manage-workspaces-modal (F03); Escape closes it. Immediately after creating that empty workspace conversation, control-openhands conversation status <id> reads idle; inspecting the conversation-status-active class shows a green dot with no animation class. Known failure (reproduced 2026-10-12, #16752): this empty idle row retains active green styling instead of the expected neutral state; the older report's flashing animation was not observed.

Row opens its conversationF04.cardKnown issueBlocked

Scenario F04--row-opens-its-conversation · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Open /.
  2. Do
    Choose “Conversation card” / containing “pong”.
  3. Wait
    Wait for “Agent message” to appear.

Expect

a row shows a status dot, the title and the relative time, links to /conversations/<id>, and the open conversation's row is highlighted.

Linked known issues

Known issue #17497 (F04.card): Corrupted conversation data breaks the entire conversation history list instead of handling individual broken conversations. Live prerequisite: The original corrupted persisted conversation or a deterministic corruption fixture after model-switch failure and fork.

Known issue #16750 (F04.card): Conversation list does not load while automation is running. Live prerequisite: A prompt automation or native delegated task that remains running during conversation-list reload; no usable model is configured here.

Known issue #15946 (F04.card): Show conversations hidden by active/stale agent-server leases. Live prerequisite: A copied lease-bearing persisted conversation and second owner/expired-lease state; never alter another live run's state.

Known issue OpenHands/software-agent-sdk#4987 (F04.card): Autotitle input has broken user-message separators and emoji-list formatting; verify the resulting visible title with a real provider. Live prerequisite: A working autotitle model and captured title-generation input/output; Canvas only consumes the resulting server title.

Known issue OpenHands/software-agent-sdk#4537 (F04.card): A native delegated task can freeze the sidebar conversation list and cause request timeouts until it ends. Live prerequisite: A working model with native TaskTool delegation holding the parent state lock during list reload.

Known issue OpenHands/software-agent-sdk#4080 (F04.card): One unregistered persisted tool observation can make a whole conversation disappear from the list and return404. Live prerequisite: A copied persisted conversation with its original unregistered observation kind and missing tool-module registration.

Exact CLI recipe & bug checks

From / (control-openhands browser goto /; the previous bullet's launch left a conversation page, where --expect-url '/conversations/' would pass at once) run control-openhands browser click 'testid=conversation-card >> has-text=pong' --expect-url '/conversations/', then control-openhands browser attr 'testid=conversation-card >> has-text=pong' data-active (true; other rows false). control-openhands browser eval "document.querySelector('[data-testid=conversation-card][data-active=true]').closest('a').getAttribute('href')" is /conversations/<id>?backend=default-local. The finished conversation shows testid=conversation-status-check, idle ones conversation-status-active (green), paused ones conversation-status-paused (grey). The reopened chat has its transcript back: control-openhands browser wait 'testid=agent-message', then control-openhands browser text 'testid=agent-message >> nth=-1' is pong and control-openhands browser text 'testid=user-message >> nth=-1' is the prompt, with control-openhands browser count 'testid=error-message-banner' 0 (browser screenshot --feature F04.card --name reopened).

Live statusF04.card-live-statusMapped behavior

Scenario F04--live-status · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Start a conversation with the prompt “Reply with only the word ping. Do not run any tools.”.
  2. Wait
    Wait for “Conversation panel” / “Conversation status working” to appear.
  3. Wait
    Wait for the conversation to finish.
  4. Wait
    Wait for the element identified in the CLI recipe to appear.

Expect

while the agent runs, its row shows the working indicator; once it finishes the row switches to the check mark and the generated title on the next list refresh.

Exact CLI recipe & bug checks

Run control-openhands conversation start --prompt "Reply with only the word ping. Do not run any tools." (no --wait; one tiny model call), then control-openhands browser wait 'testid=conversation-panel >> testid=conversation-status-working' --timeout 20000: the active row (Conversation <id5>) shows the working indicator. After control-openhands conversation wait <id> --timeout 180 reports finished, control-openhands browser wait 'testid=conversation-panel >> [data-testid=conversation-card][data-active=true] >> testid=conversation-status-check' --timeout 60000 succeeds and control-openhands browser text 'testid=conversation-panel >> [data-testid=conversation-card][data-active=true] >> testid=conversation-card-title' is the generated title (it varies: ✅ Reply with only ping, ✅ Reply only ping, no tools). The row lags the conversation by up to about 40 s (list refresh).

Group by workspaceF04.grouped-foldersKnown failure

Scenario F04--group-by-workspace · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversation layouts toggle”.
  2. Do
    Choose “Layout preset by workspace”.
  3. Do
    Start with a fresh browser profile.
  4. Do
    Follow the onboarding setup in the recipe.

Expect

By workspace shows one folder per known workspace (empty ones included) plus a No workspace folder while any loaded row has no workspace, in any browser.

Known bug observations

known failure).

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=conversation-layouts-toggle', control-openhands browser click 'testid=layout-preset-by-workspace', then control-openhands browser snapshot 'testid=conversation-panel'. Regions No workspace, qa-f04-repo and qa-f04-folder each list their own conversations; a workspace without conversations still gets a folder. Second view in another browser: control-openhands browser reset, control-openhands onboard --skip, choose By workspace again; the workspace conversations must still be in their folders (currently they all fall into No workspace, a known failure).

Collapse one folderF04.folder-collapseMapped behavior

Scenario F04--collapse-one-folder · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose the element identified in the CLI recipe.

Expect

a folder heading collapses and expands that folder.

Exact CLI recipe & bug checks

Run control-openhands browser click '[data-testid^="thread-folder-drag-ws-"][data-testid$="qa-f04-repo"]', control-openhands browser attr '[data-testid^="thread-folder-drag-ws-"][data-testid$="qa-f04-repo"]' aria-expanded (false) and control-openhands browser count '[data-testid^="thread-folder-ws-"][data-testid$="qa-f04-repo"] >> testid=conversation-card' (0). Click again: true and the cards return.

Collapse allF04.collapse-allMapped behavior

Scenario F04--collapse-all · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversations header toggle”.

Expect

the Conversations header collapses every folder, then expands them all.

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=conversations-header-toggle', control-openhands browser attr 'testid=conversations-header-toggle' aria-expanded (false) and control-openhands browser count 'testid=conversation-panel-list-scroll >> testid=conversation-card' (0). Click again: true and every card is back.

New conversation in a folderF04.folder-new-conversationMapped behavior

Scenario F04--new-conversation-in-a-folder · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Open /.
  2. Do
    Choose “Start new conversation in qa-f04-folder”.
  3. Do
    Open /.

Expect

a folder's + starts a conversation in that workspace and opens it.

Exact CLI recipe & bug checks

Run control-openhands browser goto /, then control-openhands browser click 'role=button[name="Start new conversation in qa-f04-folder"]' --expect-url '/conversations/' (returns the new /conversations/<id>), then control-openhands browser count '[data-testid^="thread-folder-ws-"][data-testid$="qa-f04-folder"] >> testid=conversation-card'; it grows by one. Repeating browser goto / plus the click for qa-f04-repo 18 times arranges the data for the next two bullets.

Folder previewF04.folder-preview-moreMapped behavior

Scenario F04--folder-preview · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    With more than five conversations in qa-f04-repo, control-openhands browser count '[data-testid^="thread-folder-ws-"][data-testid$="qa-f04-repo"] >> testid=conversation-card' is 5 and control-openhands browser text '[data-testid^="thread-folder-view-more-ws-"][data-testid$="qa-f04-repo"]' is More. Click that button: every loaded row shows and the label is Less; click again: 5.

Expect

a folder shows five rows; More shows every loaded row, Less returns to five.

Exact CLI recipe & bug checks

With more than five conversations in qa-f04-repo, control-openhands browser count '[data-testid^="thread-folder-ws-"][data-testid$="qa-f04-repo"] >> testid=conversation-card' is 5 and control-openhands browser text '[data-testid^="thread-folder-view-more-ws-"][data-testid$="qa-f04-repo"]' is More. Click that button: every loaded row shows and the label is Less; click again: 5.

Reorder foldersF04.folder-reorderMapped behavior

Scenario F04--reorder-folders · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Use browser drag as specified in the exact recipe.
  2. Do
    Reload the page.

Expect

dragging a folder heading onto another reorders the folders and the order persists.

Exact CLI recipe & bug checks

In By workspace mode read the order with control-openhands browser eval "[...document.querySelectorAll('[data-testid^=thread-folder-drag-]')].map(e=>e.textContent.trim())", then run control-openhands browser drag '[data-testid^="thread-folder-drag-ws-"][data-testid$="qa-f04-folder"]' '[data-testid^="thread-folder-drag-ws-"][data-testid$="qa-f04-repo"]' --position before. The same eval now starts with qa-f04-folder, qa-f04-repo, also after browser reload, and control-openhands browser eval "JSON.parse(localStorage.getItem('conversation-panel-preferences')).state.groupFolderOrder" lists the ws:<path> keys in that order.

Load moreF04.load-moreMapped behavior

Scenario F04--load-more · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Load more conversations”.
  2. Wait
    Wait for “Load more conversations” to disappear.
  3. Do
    Reload the page.

Expect

20 conversations load first; Load more fetches the rest and disappears when nothing is left.

Exact CLI recipe & bug checks

In By date mode (More options → testid=organize-chronological, or the Recent preset) with 22 or more conversations, control-openhands browser count 'testid=conversation-panel-list-scroll >> testid=conversation-card' is 20. Run control-openhands browser click 'testid=load-more-conversations' and control-openhands browser wait 'testid=load-more-conversations' --state detached --timeout 15000; the count is the total (23 with 23 conversations). In By workspace mode (organize-grouped, then browser reload) the same click adds the later rows to their own folders: with the oldest rows in No workspace and none of them loaded, testid=thread-folder-__none_workspace appears only after the click and browser count 'testid=conversation-card' grows by the number of unloaded No workspace rows (6 → 9 with three such rows, 5 → 7 with two). A folder that already shows five rows keeps the extra ones behind its More.

OrganizeF04.organizeMapped behavior

Scenario F04--organize · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversation layouts toggle”.
  2. Do
    Choose “Advanced options row”.
  3. Do
    Choose “Organize chronological”.
  4. Do
    Choose “Advanced options close”.
  5. Do
    Reload the page.

Expect

More options → Organize switches between folders (By workspace) and a flat list (By date); the choice survives a reload.

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=conversation-layouts-toggle', control-openhands browser click 'testid=advanced-options-row', control-openhands browser snapshot 'testid=advanced-conversation-options-modal' (sections Organize, Sort by, Threads, Additional, Automations, Metadata), control-openhands browser click 'testid=organize-chronological' (browser attr 'testid=organize-chronological' aria-checked is true), control-openhands browser click 'testid=advanced-options-close', control-openhands browser reload, then control-openhands browser count '[data-testid^=thread-folder-ws-]'. The count is 0 and the rows form one list; organize-grouped brings the folders back.

Header dividerF04.list-headerMapped behavior

Scenario F04--header-divider · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Scroll “Conversation panel list scroll” as specified in the recipe.

Expect

the header divider appears only while the list is scrolled.

Exact CLI recipe & bug checks

With more rows than fit (By date mode with 20 loaded rows, as Organize leaves it; By workspace mode previews too few rows to scroll), control-openhands browser eval "document.querySelector('[data-testid=older-conversations-summary]').parentElement.classList.contains('border-border')" is false; after control-openhands browser scroll 'testid=conversation-panel-list-scroll' --by 300 it is true, and false again after --by -300.

RenameF04.card-renameMapped behavior

Scenario F04--rename · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Load more conversations”.
  2. Wait
    Wait for “Load more conversations” to disappear.
  3. Do
    Scroll “Conversation card” / containing “Conversation <id5>” as specified in the recipe.
  4. Do
    Hover over “Conversation card” / containing “Conversation <id5>”.
  5. Do
    Choose “Conversation card” / containing “Conversation <id5>” / “More options”.
  6. Do
    Choose “Context menu” / “Edit”.
  7. Do
    Enter “QA_F04 renamed” in the element identified in the CLI recipe.
  8. Do
    Press Enter.
  9. Do
    Reload the page.

Expect

⋮ → Rename edits the title inline; Enter saves, a toast confirms, and the title persists.

Exact CLI recipe & bug checks

Pick the oldest untitled conversation (b8d99... from the picker step; the sort check below needs an old one). It is beyond the first 20 rows after a reload, so first run control-openhands browser click 'testid=load-more-conversations' and control-openhands browser wait 'testid=load-more-conversations' --state detached --timeout 15000. Then run control-openhands browser scroll 'testid=conversation-card >> has-text=Conversation <id5>' (the first five characters of its id), control-openhands browser hover 'testid=conversation-card >> has-text=Conversation <id5>', control-openhands browser click 'testid=conversation-card >> has-text=Conversation <id5> >> testid=ellipsis-button', control-openhands browser click 'testid=context-menu >> testid=edit-button', control-openhands browser fill 'input[data-testid=conversation-card-title]' 'QA_F04 renamed', control-openhands browser press Enter, then control-openhands browser toasts (Conversation title updated successfully), control-openhands browser reload and control-openhands browser count 'testid=conversation-card-title >> has-text=QA_F04 renamed' (1).

SortF04.sortMapped behavior

Scenario F04--sort · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Sort created”.
  2. Do
    Choose “Advanced options close”.

Expect

Sort by Updated or Created reorders the list.

Exact CLI recipe & bug checks

Under Sort by Updated (default) the just-renamed old conversation is first. Sorting applies to the loaded rows only: after a reload the first page is the 20 most recently updated. In More options run control-openhands browser click 'testid=sort-created' and control-openhands browser click 'testid=advanced-options-close'; control-openhands browser eval "[...document.querySelectorAll('[data-testid=conversation-panel-list-scroll] [data-testid=conversation-card-title]')].map(e=>e.textContent)" now ends with QA_F04 renamed (with every page loaded, the older pong row comes after it), and the View menu row reads More options · Custom. Restore with testid=layout-preset-recent-activity.

StopF04.stopMapped behavior

Scenario F04--stop · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Context menu” / “Stop”.
  2. Do
    Choose the dialog / “Cancel”.
  3. Wait
    Wait for the conversation to finish.
  4. Wait
    Wait for “Conversation card” / containing “Conversation <id5>” / “Conversation status paused” to appear.
  5. Do
    Press Escape.

Expect

⋮ → Stop Conversation asks for confirmation and pauses the conversation; the item is gone once paused.

Exact CLI recipe & bug checks

On an idle row open ⋮ and run control-openhands browser click 'testid=context-menu >> testid=stop-button'; control-openhands browser snapshot 'role=dialog' reads Confirm Stop Conversation, Are you sure you want to stop this conversation?, and control-openhands browser testids 'role=dialog' lists cancel-button (Cancel) and confirm-button (Confirm Close). control-openhands browser click 'role=dialog >> testid=cancel-button' keeps it idle (control-openhands conversation status <id>). Repeat and click 'role=dialog >> testid=confirm-button'; control-openhands conversation wait <id> --until paused --timeout 30 reaches paused, control-openhands browser wait 'testid=conversation-card >> has-text=Conversation <id5> >> testid=conversation-status-paused' succeeds, and the reopened ⋮ menu has no Stop item. control-openhands browser press Escape closes it (browser count 'testid=context-menu' is 0) and puts focus back on the row's ⋮ (control-openhands browser eval "document.activeElement.dataset.testid" is ellipsis-button).

PresetsF04.presetsMapped behavior

Scenario F04--presets · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversation layouts toggle”.
  2. Do
    Choose “Layout preset recent activity”.
  3. Do
    Reload the page.

Expect

a preset is checked and survives a reload; Active and Compact hide paused conversations; any manual change reads More options · Custom.

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=conversation-layouts-toggle', control-openhands browser click 'testid=layout-preset-recent-activity', control-openhands browser reload, reopen the menu, then control-openhands browser attr 'testid=layout-preset-recent-activity' aria-checked (true) and control-openhands browser text 'testid=advanced-options-row' (More options). With the paused conversation from Stop (above), testid=layout-preset-focused (Active) and testid=layout-preset-minimal (Compact) make control-openhands browser count 'testid=conversation-card >> has-text=Conversation <id5>' 0; Recent shows it again.

Threads scopeF04.thread-scopeMapped behavior

Scenario F04--threads-scope · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Scope relevant”.
  2. Do
    Choose “Advanced options close”.
  3. Do
    Reload the page.

Expect

More options → Threads → Active only hides paused conversations; All threads shows them again.

Exact CLI recipe & bug checks

With the paused conversation from Stop and the Recent preset, open More options and run control-openhands browser click 'testid=scope-relevant' (browser attr 'testid=scope-relevant' aria-checked is true) and control-openhands browser click 'testid=advanced-options-close': control-openhands browser count 'testid=conversation-card >> has-text=Conversation <id5>' is 0, also after browser reload, and the View menu now checks no preset and reads More options · Custom (Recent shows old conversations; the Active preset also hides them). testid=scope-all brings the row back (1) and Recent is checked again.

Hide olderF04.hide-olderMapped behavior

Scenario F04--hide-older · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Older conversation cutoff”.
  2. Do
    Choose “Over 1 hour”.
  3. Do
    Choose “Toggle older conversations” / “Hide old conversations”.
  4. Do
    Choose “Advanced options close”.
  5. Do
    Reload the page.
  6. Do
    Use browser storage as specified in the exact recipe.

Expect

Hide old conversations offers four cutoffs, persists the choice and hides conversations older than it.

Exact CLI recipe & bug checks

In More options, control-openhands browser attr 'testid=toggle-older-conversations' aria-checked is false (Recent shows conversations of every age) and control-openhands browser text 'testid=older-conversation-cutoff' is Over 1 week. Run control-openhands browser click 'testid=older-conversation-cutoff' (radios Over 1 hour, Over 1 day, Over 1 week, Over 30 days), control-openhands browser click 'role=menuitemradio[name="Over 1 hour"]', then control-openhands browser click 'testid=toggle-older-conversations >> text=Hide old conversations' (aria-checked turns true; a click on the row's center lands on the cutoff dropdown instead), control-openhands browser click 'testid=advanced-options-close', control-openhands browser reload, then control-openhands browser storage --values: conversation-panel-preferences holds "showOlderConversations":false and "olderConversationCutoff":"1h", and the View menu reads More options · Custom. Restore with testid=layout-preset-recent-activity (it turns hiding off but keeps the cutoff) and the cutoff Over 1 week. Hiding itself needs a conversation last updated before the cutoff (not reachable on a fresh run).

Automation filterF04.automation-filterMapped behavior

Scenario F04--automation-filter · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Automation filter only”.
  2. Do
    Choose “Advanced options close”.

Expect

More options → Automations shows all, hides or keeps only automation runs, with its own empty message.

Exact CLI recipe & bug checks

In More options run control-openhands browser click 'testid=automation-filter-only' and control-openhands browser click 'testid=advanced-options-close'; with no automation runs control-openhands browser text 'testid=conversation-panel-empty-state' is No conversations match the automation filter (Load more stays). testid=automation-filter-hide keeps every manual conversation; testid=automation-filter-all restores the default. Unpin everything first: a pinned row suppresses the empty state.

Row metadataF04.metadata-togglesMapped behavior

Scenario F04--row-metadata · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    In More options click testid=toggle-repo-branch-metadata, testid=toggle-llm-profiles and testid=toggle-tags-metadata, then testid=advanced-options-close. control-openhands browser testids 'testid=conversation-card >> has-text=Conversation <id5>' lists conversation-card-workspace-folder (qa-f04-repo) and conversation-card-agent-chip (deepseek-flash) and no conversation-card-tag-chip. Restore with testid=layout-preset-recent-activity (presets reset all metadata toggles).

Expect

Repo and branch, Agent / model and Show tags add or remove row chips.

Exact CLI recipe & bug checks

In More options click testid=toggle-repo-branch-metadata, testid=toggle-llm-profiles and testid=toggle-tags-metadata, then testid=advanced-options-close. control-openhands browser testids 'testid=conversation-card >> has-text=Conversation <id5>' lists conversation-card-workspace-folder (qa-f04-repo) and conversation-card-agent-chip (deepseek-flash) and no conversation-card-tag-chip. Restore with testid=layout-preset-recent-activity (presets reset all metadata toggles).

Hover previewF04.hover-previewMapped behavior

Scenario F04--hover-preview · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Use browser mouse click as specified in the exact recipe.
  2. Do
    Use browser tooltip as specified in the exact recipe.
  3. Do
    Use browser tooltip as specified in the exact recipe.

Expect

hovering a row for a second shows title, directory, model and creation time, unless Details on hover is off.

Exact CLI recipe & bug checks

Run control-openhands browser mouse-click 900 900, then control-openhands browser tooltip 'testid=conversation-card >> has-text=Conversation <id5>'. The text is the title, Directory with the workspace path, Model deepseek/deepseek-flash and Created with a date. After testid=toggle-hover-metadata is off (aria-checked false), control-openhands browser tooltip ... --timeout 5000 finds no tooltip.

PinF04.pinMapped behavior

Scenario F04--pin · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Hover over “Conversation card” / containing “QA_F04 renamed”.
  2. Do
    Choose the element identified in the CLI recipe.
  3. Do
    Reload the page.
  4. Do
    Hover over the current page.
  5. Do
    Choose the current page.

Expect

the pin moves a row into a Pinned section above the list, survives a reload and unpins from there.

Exact CLI recipe & bug checks

Run control-openhands browser hover 'testid=conversation-card >> has-text=QA_F04 renamed', control-openhands browser click 'testid=conversation-card >> has-text=QA_F04 renamed >> [data-testid^=conversation-pin-toggle-]', then control-openhands browser text 'testid=conversation-panel-pinned-section' (Pinned and the row), control-openhands browser count 'testid=conversation-card >> has-text=QA_F04 renamed' (1: not duplicated) and, after browser reload, control-openhands browser attr 'testid=conversation-panel-pinned-section >> [data-testid^=conversation-pin-toggle-]' aria-pressed (true). Unpin with browser hover and browser click on testid=conversation-panel-pinned-section >> testid=conversation-card and its [data-testid^=conversation-pin-toggle-]; after a reload browser count 'testid=conversation-panel-pinned-section' is 0.

Pinned previewF04.pinned-preview-moreMapped behavior

Scenario F04--pinned-preview · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Scroll the current page as specified in the recipe.
  2. Do
    Hover over the current page.
  3. Do
    Choose “Conversation panel pinned view more”.
  4. Do
    Hover over the current page.

Expect

the Pinned section previews five rows; its More shows every pinned row and Less returns to five.

Exact CLI recipe & bug checks

Pin six rows (browser scroll, browser hover, then click each row's [data-testid^=conversation-pin-toggle-]). control-openhands browser count 'testid=conversation-panel-pinned-section >> testid=conversation-card' is 5 and control-openhands browser text 'testid=conversation-panel-pinned-view-more' is More; control-openhands browser click 'testid=conversation-panel-pinned-view-more' makes the count 6 and the label Less; click again: 5. Unpin all six with browser hover and a pin click on 'testid=conversation-panel-pinned-section >> testid=conversation-card >> nth=0', repeated.

Edit tagsF04.edit-tagsMapped behavior

Scenario F04--edit-tags · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Context menu” / “Edit tags”.
  2. Do
    Enter “Bad Key” in “New tag key”.
  3. Do
    Press Enter then --selector then testid=new-tag-key-input.
  4. Do
    Enter “one” in “New tag value”.
  5. Do
    Choose “Edit conversation tags modal” / “Confirm”.
  6. Do
    Reload the page.

Expect

⋮ → Edit tags adds and removes key: value tags with validation; Save shows Tags updated and the chips persist.

Exact CLI recipe & bug checks

Open ⋮ on a row (hover, testid=ellipsis-button) and run control-openhands browser click 'testid=context-menu >> testid=edit-tags-button'. Then: control-openhands browser fill 'testid=new-tag-key-input' 'Bad Key' and control-openhands browser press Enter --selector 'testid=new-tag-key-input' → control-openhands browser text 'testid=edit-tags-error' is Tag names may only contain lowercase letters and numbers (it uses the feedback-error colour, #18330: control-openhands browser eval "getComputedStyle(document.querySelector('[data-testid=edit-tags-error]')).color" is rgb(231, 106, 94) on OpenHands-Neutral and rgb(192, 40, 45) on Light+, readable on the light dialog; switch themes as in F16.color-theme and restore OpenHands-Neutral); key title with testid=add-tag-button → This tag name is reserved; key qaenv, browser fill 'testid=new-tag-value-input' one, Enter → browser count 'testid=edit-tag-row-qaenv' is 1; key qaenv again → This tag name is already in use; key qalong with a 257-character value → Tag values must be 256 characters or fewer; key qabare with an empty value left in the inputs, then control-openhands browser click 'testid=edit-conversation-tags-modal >> testid=confirm-button'. control-openhands browser toasts shows Tags updated; after browser reload the row shows chips Qabare and Qaenv: one (conversation-card-tag-chip), and control-openhands api GET '/api/conversations/search?limit=3' has tags qaenv: one, qabare: "".

Tag overflowF04.tag-overflowMapped behavior

Scenario F04--tag-overflow · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Reload the page.
  2. Do
    Press Escape.

Expect

tags that do not fit on a row collapse into a +N chip (aria Show N more tags) whose popover lists the hidden tags without opening the conversation; Escape closes it.

Exact CLI recipe & bug checks

On the tagged row add three more tags in Edit tags (keys qaregion, qastage, qaowner, values value-for-<key>, Enter after each) and save. After browser reload the row shows Qabare and Qaenv: one plus control-openhands browser text 'testid=conversation-card >> has-text=Conversation <id5> >> testid=conversation-card-tag-overflow' +3 (aria-label Show 3 more tags). Clicking it keeps the URL, sets aria-expanded true, and control-openhands browser text 'testid=conversation-card-tag-overflow-popover' lists Qaowner value-for-qaowner, Qaregion …, Qastage … (3 conversation-card-tag-overflow-row); control-openhands browser press Escape closes it (count 0).

Remove tagsF04.edit-tags-removeMapped behavior

Scenario F04--remove-tags · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Remove tag qaregion”.
  2. Do
    Reload the page.

Expect

in Edit tags each row's remove button drops that tag; Save persists the removal on the server.

Exact CLI recipe & bug checks

Reopen Edit tags on that row and run control-openhands browser click 'testid=remove-tag-qaregion' (likewise remove-tag-qastage, remove-tag-qaowner); control-openhands browser count 'testid=edit-tags-rows >> [data-testid^=edit-tag-row-]' is 2. Save with testid=edit-conversation-tags-modal >> testid=confirm-button (Tags updated); after browser reload the +3 chip is gone and control-openhands api GET '/api/conversations/search?limit=1' --pick items.0.tags is clientsource, qabare, qaenv only.

Tag filterF04.tag-filterMapped behavior

Scenario F04--tag-filter · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversation layouts toggle”.
  2. Do
    Choose “Tag filters section”.
  3. Do
    Choose “Tag facet row qaenv=one”.
  4. Do
    Press Escape.
  5. Do
    Reload the page.

Expect

choosing a tag facet narrows the list to rows with that tag (pins exempt) and survives a reload.

Exact CLI recipe & bug checks

After Edit tags (above) gave one row qaenv=one, run control-openhands browser click 'testid=conversation-layouts-toggle', control-openhands browser click 'testid=tag-filters-section', control-openhands browser click 'testid=tag-facet-row-qaenv=one' (aria-checked true; the menu stays open), control-openhands browser press Escape, then control-openhands browser count 'testid=conversation-panel-list-scroll >> testid=conversation-card': only the tagged row plus pinned rows. The count is the same after browser reload.

Filter chipsF04.filter-chipsMapped behavior

Scenario F04--filter-chips · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Active tag filter qaenv=one”.
  2. Do
    Choose “Clear tag filters”.

Expect

active filters show as chips above the list; a chip click removes one, Clear all removes every chip.

Exact CLI recipe & bug checks

With the facet active, control-openhands browser text 'testid=conversation-active-tag-filters' is qaenv=one and Clear all. control-openhands browser click 'testid=active-tag-filter-qaenv=one' removes it (browser count 'testid=conversation-active-tag-filters' is 0). Select tag-facet-row-qaenv=one and tag-facet-row-qabare= again, then control-openhands browser click 'testid=clear-tag-filters': the strip disappears and the full list returns.

Automation setup tagF04.automation-setup-tagMapped behavior

Scenario F04--automation-setup-tag · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Open /automations.
  2. Do
    Choose “Automations add automation”.
  3. Do
    Choose “Automations add automation create”.
  4. Do
    Start a conversation with the prompt “Reply with only the word ok. Do not run any tools.”.
  5. Do
    Choose “Conversation layouts toggle”.
  6. Do
    Choose “Tag filters section”.
  7. Do
    Press Escape.
  8. Do
    Choose “Active tag filter automationsetup=draft”.
  9. Do
    Use browser mouse click as specified in the exact recipe.
  10. Do
    Use browser tooltip as specified in the exact recipe.
  11. Do
    Open /.

Expect

a conversation started from the automation setup page shows an Automation setup: Draft chip (lightning icon) first in its tag row; Filter by tags offers a facet and filter chip of the same name, and the hover preview lists Automation setup draft.

Exact CLI recipe & bug checks

Arrange one setup conversation through the setup page (F22): control-openhands browser goto /automations, control-openhands browser click 'testid=automations-add-automation', control-openhands browser click 'testid=automations-add-automation-create' --expect-url '/automations/setup', then control-openhands conversation start --stay --prompt 'Reply with only the word ok. Do not run any tools.' --wait --timeout 180 (one tiny model call; note <setup-id>). control-openhands api GET /api/conversations/<setup-id> --pick tags has automationsetup: draft. In the sidebar, control-openhands browser text 'testid=conversation-card >> has-text=Reply >> testid=conversation-card-tag-chip' is Automation setup: Draft (the first chip; the internal draft-id keys stay hidden). Run control-openhands browser click 'testid=conversation-layouts-toggle', control-openhands browser click 'testid=tag-filters-section': the facet testid=tag-facet-row-automationsetup=draft reads Automation setup: Draft; click it, control-openhands browser press Escape, and control-openhands browser text 'testid=conversation-active-tag-filters' is Automation setup: Draft and Clear all, with only setup conversations (and pinned rows) left; control-openhands browser click 'testid=active-tag-filter-automationsetup=draft' removes it. After control-openhands browser mouse-click 900 900, control-openhands browser tooltip 'testid=conversation-card >> has-text=Reply' lists Automation setup and the raw value draft (browser screenshot --feature F04.automation-setup-tag --name facet). End with control-openhands browser goto /; the setup send leaves no Home draft, and opening another conversation from the sidebar leaves that conversation's tags alone (see Gotchas).

DownloadF04.downloadMapped behavior

Scenario F04--download · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Context menu” / “Download trajectory”.

Expect

⋮ → Download conversation data saves conversation_<id>.zip.

Exact CLI recipe & bug checks

Open ⋮ and run control-openhands browser click 'testid=context-menu >> testid=download-trajectory-button', then control-openhands browser downloads. A file …-conversation_<id>.zip lands in <run>/private/downloads; control-openhands browser downloads --last 1 --inspect lists <id-hex>/base_state.json and meta.json for any row, plus event folders such as bash_events/ for a conversation that ran (the pong row; it is the oldest, so Load more first).

Download failureF04.download-errorMapped behavior

Scenario F04--download-failure · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Setup
    Change the run-owned service state: stop agent-server.
  2. Do
    Restart the run-owned stack as specified.

Expect

a failed download shows one toast and closes the ⋮ menu. When the Agent Server is down behind a plain-text 502 ingress response, the toast uses the generic error fallback rather than raw transport text.

Exact CLI recipe & bug checks

With ⋮ already open on a row, run control-openhands browser errors --clear and control-openhands service stop agent-server, click testid=context-menu >> testid=download-trajectory-button, then control-openhands browser toasts --history and control-openhands browser count 'testid=context-menu'. There is exactly one toast, Couldn't download the conversation data: An error occurred, and the menu is closed (0). The download request returned a plain-text ingress 502; getApiErrorMessage intentionally omits raw transport text and falls back to this generic message when the response body has no usable error field. control-openhands browser errors --app-only has pageErrors 0; its 502 request and console error are the outage itself. Run control-openhands restart and control-openhands doctor afterwards.

ArchiveF04.archiveMapped behavior

Scenario F04--archive · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Context menu” / “Archive”.
  2. Do
    Choose the dialog / “Cancel”.
  3. Do
    Choose the dialog / “Confirm”.
  4. Do
    Reload the page.

Expect

⋮ → Archive Conversation asks for confirmation, hides and unpins the row, and leaves the conversation if it was open.

Exact CLI recipe & bug checks

Open a conversation from its row, open ⋮ and run control-openhands browser click 'testid=context-menu >> testid=archive-button'; control-openhands browser snapshot 'role=dialog' reads Archive conversation and Archive "<title>"? The conversation stays available with its full history and can be restored from Show archived. control-openhands browser click 'role=dialog >> testid=cancel-button' keeps the row. Repeat and control-openhands browser click 'role=dialog >> testid=confirm-button' --expect-url '/conversations(\?|$)'; the row count is 0, also after browser reload. Archiving a pinned row removes the Pinned section.

Show archived and UnarchiveF04.show-archived-unarchiveKnown issueBlocked

Scenario F04--show-archived-and-unarchive · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Context menu” / “Unarchive”.

Expect

Show archived brings archived rows back with an Archived chip; Unarchive restores a row without confirmation.

Linked known issues

Known issue #18155 (F04.show-archived-unarchive): Missing-runtime conversations shown as Archived but never hidden, chipped, or unarchivable. Live prerequisite: A Cloud sandbox or local runtime that becomes MISSING and non-resumable; ordinary local pause remains resumable.

Exact CLI recipe & bug checks

In More options click testid=toggle-show-archived (aria-checked true) and testid=advanced-options-close; control-openhands browser count 'testid=conversation-card >> has-text=Conversation <id5> >> testid=conversation-card-archived-chip' is 1 and the ⋮ menu offers Unarchive Conversation. control-openhands browser click 'testid=context-menu >> testid=unarchive-button' opens no dialog (browser count 'role=dialog' 0) and the chip count drops to 0. Turn Show archived off again.

DeleteF04.deleteMapped behavior

Scenario F04--delete · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Context menu” / “Delete”.
  2. Do
    Choose the dialog / “Cancel”.
  3. Do
    Choose the dialog / “Confirm”.
  4. Do
    Reload the page.

Expect

⋮ → Delete Conversation asks for confirmation, deletes it on the server and leaves it if it was open.

Exact CLI recipe & bug checks

Open a conversation from its row, open ⋮ and run control-openhands browser click 'testid=context-menu >> testid=delete-button'; the dialog reads Confirm Delete and Are you sure you want to delete the "<title>" conversation? This action cannot be undone. with cancel-button and confirm-button. control-openhands browser click 'role=dialog >> testid=cancel-button' keeps the row. Repeat and control-openhands browser click 'role=dialog >> testid=confirm-button' --expect-url '/conversations(\?|$)'; after browser reload the row count is 0 and control-openhands api GET /api/conversations/<id> is 404.

PhoneF04.phoneMapped behavior

Scenario F04--phone · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Setup
    Use the phone viewport.
  2. Do
    Open /.
  3. Do
    Choose “Sidebar mobile menu toggle”.
  4. Do
    Use browser mouse click as specified in the exact recipe.
  5. Wait
    Wait for “Sidebar mobile drawer” to disappear.
  6. Do
    Choose “Sidebar mobile drawer” / “Conversation card” / containing “QA_F04 renamed”.
  7. Wait
    Wait for “Sidebar mobile drawer” to disappear.
  8. Setup
    Use the desktop viewport.

Expect

at 390 px the list lives in the sidebar drawer, fits the viewport, and picking a row closes the drawer.

Exact CLI recipe & bug checks

Run control-openhands browser viewport phone, control-openhands browser goto /, control-openhands browser click 'testid=sidebar-mobile-menu-toggle', then control-openhands browser bbox 'testid=sidebar-mobile-drawer >> testid=conversation-panel' (insideViewport true, pageHorizontalOverflow false) and control-openhands browser screenshot --feature F04.phone --name drawer. Hover a row in the drawer and click its testid=ellipsis-button; control-openhands browser bbox 'testid=context-menu' is inside the viewport. control-openhands browser mouse-click 380 20 closes the menu (browser count 'testid=context-menu' 0) and the drawer (control-openhands browser wait 'testid=sidebar-mobile-drawer' --state hidden --timeout 5000; an immediate visible still reads true during the slide-out). Reopen the drawer and control-openhands browser click 'testid=sidebar-mobile-drawer >> testid=conversation-card >> has-text=QA_F04 renamed' --expect-url '/conversations/'; control-openhands browser wait 'testid=sidebar-mobile-drawer' --state hidden --timeout 5000 succeeds. Return with control-openhands browser viewport desktop.

A later-page pinF04.pinKnown failure

Scenario F04--a-later-page-pin · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Hover over the current page.
  2. Do
    Reload the page.

Expect

the pin moves a row into a Pinned section above the list, survives a reload and unpins from there.

Known bug observations

Known failure (reproduced 2026-10-12, #16399): the later-page pin is pruned on first-page reload even though the conversation still exists. Tested with 23 empty conversations and one older pin.

Exact CLI recipe & bug checks

With more than 20 conversations as the pagination precondition already arranges, choose Recent, reload, click role=button[name="Load more"], and pin a conversation from the newly loaded rows (browser hover its conversation-card, then click its [data-testid^=conversation-pin-toggle-]). Read the pinned section, then control-openhands browser reload and control-openhands browser count 'testid=conversation-panel-pinned-section'. Known failure (reproduced 2026-10-12, #16399): the later-page pin is pruned on first-page reload even though the conversation still exists. Tested with 23 empty conversations and one older pin.

Fresh-browser groupingF04.grouped-foldersKnown failure

Scenario F04--fresh-browser-grouping · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Start with a fresh browser profile.
  2. Do
    Follow the onboarding setup in the recipe.
  3. Do
    Choose “Conversation layouts toggle”.
  4. Do
    Choose “Layout preset by workspace”.

Expect

By workspace shows one folder per known workspace (empty ones included) plus a No workspace folder while any loaded row has no workspace, in any browser.

Known bug observations

Known failure (reproduced 2026-10-12, #17386): existing conversations move to No workspace although their server working directory still matches the registered workspace. The reset clears browser metadata; do not use it before checks that depend on the original browser's grouping.

Exact CLI recipe & bug checks

Run this after the other list checks: select By workspace, record its groups, control-openhands browser reset, control-openhands onboard --skip, then control-openhands browser click 'testid=conversation-layouts-toggle' and control-openhands browser click 'testid=layout-preset-by-workspace'. Compare browser snapshot 'testid=conversation-panel' with conversation status <id>. Known failure (reproduced 2026-10-12, #17386): existing conversations move to No workspace although their server working directory still matches the registered workspace. The reset clears browser metadata; do not use it before checks that depend on the original browser's grouping.

Delete allF04.delete-allKnown issue

Scenario F04--delete-all · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Conversation layouts toggle”.
  2. Do
    Choose “Delete all conversations”.
  3. Do
    Choose the dialog / “Confirm”.
  4. Wait
    Wait for the dialog to disappear.

Expect

View → Delete all asks for confirmation with a count and deletes every conversation.

Linked known issues

Known issue #17919: Delete all deletes only the loaded pages, and its dialog states that smaller count (F04.delete-all).

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=conversation-layouts-toggle', control-openhands browser click 'testid=delete-all-conversations' and control-openhands browser snapshot 'role=dialog': Delete all conversations, Are you sure you want to delete N conversations?. Cancel (role=dialog >> testid=cancel-button) keeps every row. Confirm with control-openhands browser click 'role=dialog >> testid=confirm-button' and control-openhands browser wait 'role=dialog' --state detached --timeout 30000; control-openhands api GET '/api/conversations/search?limit=100' has no items, Delete all is disabled again, and in By date mode the empty state returns. Expected for every conversation; today N and the deletion cover only the loaded pages (22 conversations, 20 loaded: 2 remain).

Collapsed railF04.collapsed-railMapped behavior

Scenario F04--collapsed-rail · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Choose “Sidebar collapse toggle”.
  2. Do
    Choose the element identified in the CLI recipe.

Expect

the collapsed sidebar rail shows no conversation list; expanding brings it back.

Exact CLI recipe & bug checks

Run control-openhands browser click 'testid=sidebar-collapse-toggle', then control-openhands browser count 'testid=conversation-panel' (0). Expand with control-openhands browser click 'aside[data-collapsed]' (see F02); the count is 1.

Cloud picker and start tasksF04.cloud-picker · F04.start-task-cardsKnown issueBlocked

Scenario F04--cloud-picker-and-start-tasks · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    Blocked without an OpenHands Cloud backend and git provider. On Cloud, the same conversation-panel-new-thread-picker opens cloud-provider-tabs, cloud-repo-search-input (Search repositories) and launch-repository rows; start tasks render testid=start-task-card linking to /conversations/task-<id>.

Expect

on a Cloud backend the folder-plus picker shows provider tabs and a repository search; a picked repository starts a conversation.

on a Cloud backend in-progress start tasks show as cards linking to /conversations/task-<id>.

Linked known issues

Known issue #17257 (F04.start-task-cards): Cloud provisioning has no in-progress start-task cards because the list hook always returns an empty array. Live prerequisite: An authenticated Cloud backend producing an in-progress sandbox/repository start task.

Exact CLI recipe & bug checks

Blocked without an OpenHands Cloud backend and git provider. On Cloud, the same conversation-panel-new-thread-picker opens cloud-provider-tabs, cloud-repo-search-input (Search repositories) and launch-repository rows; start tasks render testid=start-task-card linking to /conversations/task-<id>.

CleanupF04 · setup / cleanupSupport step

Scenario F04--cleanup · Permalink · Source

Given

Use F04’s prerequisites and the common setup. Follow the family’s order when a script uses an earlier fixture or says “as above”.

Do — reading outline

  1. Do
    View → Delete all twice (the second pass removes the rows the first left behind), until api GET '/api/conversations/search?limit=100' is empty; re-apply the Recent preset. Fixture folders and the workspace registry vanish with the run.

Expect

Complete this support step before continuing to the next scenario.

Exact CLI recipe & bug checks

View → Delete all twice (the second pass removes the rows the first left behind), until api GET '/api/conversations/search?limit=100' is empty; re-apply the Recent preset. Fixture folders and the workspace registry vanish with the run.

Family notes, prerequisites for known issues & limits Known issueBlocked
  • A plain --expect-url '/conversations/' returns at once when the browser is already on a conversation page. Start creation clicks from / (browser goto /), and never navigate away before the click returns: leaving early skips the client-side metadata write, so the new conversation lands in No workspace although the server has its working directory.
  • Workspace grouping, pins, archives and preferences live in this browser's localStorage (openhands-agent-server-conversation-metadata, pinned-conversations, archived-conversations, conversation-panel-preferences). browser reset loses them: archived rows reappear and every conversation moves to No workspace.
  • Folder test ids embed the sanitized absolute workspace path (thread-folder-ws--tmp-...-qa-f04-repo). Select with [data-testid^="thread-folder-ws-"][data-testid$="<folder>"] or by the + button's accessible name.
  • Row links carry ?backend=default-local; anchor URL regexes without $.
  • Hover and ⋮ need the row on screen: browser scroll '<row>' first, and browser hover before clicking ellipsis-button or the pin.
  • Escape closes the ⋮ menu and returns focus to its ⋮ button (#18044); an outside browser mouse-click closes it too. If Tab has moved focus to the next row's link, that row's preview tooltip opens and takes the first Escape, so press Escape twice. Inside the phone drawer the first Escape closes the menu and the next one the drawer.
  • The Stop, Delete and Delete all dialogs name their buttons cancel-button and confirm-button, like the Archive and Edit tags dialogs (#17915, fixed by #18151); role=dialog >> role=button[name="..."] still works.
  • With the drawer open at phone width there are two conversation-panel elements; scope with testid=sidebar-mobile-drawer >> ....
  • Recent is exactly the fresh default layout (By date, Updated, all threads, old conversations shown), so a new user sees Recent checked. Active and Compact also turn on Hide old conversations: Recent plus a manual Threads → Active only reads More options · Custom, not Active. Presets never change the hide-older cutoff.
  • In By workspace mode Load more often adds no visible row: later rows join existing folders behind their More button.
  • By workspace never shows No conversations found while any workspace is registered: empty workspace folders stay.
  • Pinned rows bypass tag and automation filters and suppress the filtered empty states; unpin before asserting them.
  • The page size is 20; filters, Active scope and archives apply only to loaded pages.
  • The ⋮ menu offers Stop for idle and finished conversations too (they count as active); it disappears only once paused.
  • service stop agent-server needs control-openhands restart and a browser reload before anything else works.
  • The list refreshes on an interval: a row keeps conversation-status-working and Conversation <id5> for up to about 40 s after the conversation finished. Use browser wait ... --timeout 60000, not an immediate count.
  • Model-written titles vary from run to run; match finished conversations on a word from the prompt (has-text=pong), never on the whole title.
  • Opening a conversation from the sidebar never changes its tags, also right after an automation setup conversation (one tagged automationsetup: draft): the other conversation keeps its tags and opens as a normal chat (recipe in F07 F07.open-by-url). A conversation that did get the tag loses it with Edit tags (remove-tag-automationsetup).
  • Known issue #17919: Delete all deletes only the loaded pages, and its dialog states that smaller count (F04.delete-all).
  • Known issue #18155 (F04.show-archived-unarchive): Missing-runtime conversations shown as Archived but never hidden, chipped, or unarchivable. Live prerequisite: A Cloud sandbox or local runtime that becomes MISSING and non-resumable; ordinary local pause remains resumable.
  • Known issue #17497 (F04.card): Corrupted conversation data breaks the entire conversation history list instead of handling individual broken conversations. Live prerequisite: The original corrupted persisted conversation or a deterministic corruption fixture after model-switch failure and fork.
  • Known issue #17257 (F04.start-task-cards): Cloud provisioning has no in-progress start-task cards because the list hook always returns an empty array. Live prerequisite: An authenticated Cloud backend producing an in-progress sandbox/repository start task.
  • Known issue #16750 (F04.card): Conversation list does not load while automation is running. Live prerequisite: A prompt automation or native delegated task that remains running during conversation-list reload; no usable model is configured here.
  • Known issue #15946 (F04.card): Show conversations hidden by active/stale agent-server leases. Live prerequisite: A copied lease-bearing persisted conversation and second owner/expired-lease state; never alter another live run's state.
  • Known issue OpenHands/software-agent-sdk#4987 (F04.card): Autotitle input has broken user-message separators and emoji-list formatting; verify the resulting visible title with a real provider. Live prerequisite: A working autotitle model and captured title-generation input/output; Canvas only consumes the resulting server title.
  • Known issue OpenHands/software-agent-sdk#4537 (F04.card): A native delegated task can freeze the sidebar conversation list and cause request timeouts until it ends. Live prerequisite: A working model with native TaskTool delegation holding the parent state lock during list reload.
  • Known issue OpenHands/software-agent-sdk#4080 (F04.card): One unregistered persisted tool observation can make a whole conversation disappear from the list and return404. Live prerequisite: A copied persisted conversation with its original unregistered observation kind and missing tool-module registration.

Before you start

Use an OpenHands checkout at the source revision, with Node 24+, installed npm dependencies, uv / uvx, and a supported Chromium browser. The verification skill is the complete setup contract.

export PATH="$PWD/.agents/skills/verify-openhands/scripts:$PATH"
export OH_VERIFY_RUN=$(control-openhands launch --new --print-run)
control-openhands doctor
control-openhands onboard --skip
# Configure a model only for a scenario that needs one:
control-openhands llm preset deepseek
# When the run is complete:
control-openhands stop

F01 walks onboarding instead of skipping it. No-model checks run before model configuration. Keep OH_VERIFY_RUN set so commands address your own run. Desktop is 1440 × 1000; phone is 390 × 844. Model-backed checks need the configured provider key and budget.

Recipes run in source order within each family and can share fixtures. The page preserves that order; “as above” is a dependency on an earlier case. Setup commands and API writes arrange state. They do not prove a UI path. Follow the family cleanup steps.

A known failure preserves the intended expectation beside the observed defect. Executable known-bug blocks use xfail for a reproduced symptom and xpass when it stops reproducing. Cloud accounts, enterprise capabilities and other unavailable prerequisites remain explicit. “Not run” is different from “blocked”.

The maintained map describes application behavior at its pinned revision. Once a fix is verified in the application version under test, remove the obsolete failure note and keep the normal expectation. Dated evidence belongs in the backfill ledger.

Read the full map index and coverage boundaries, the CLI guide, or the earlier illustrated edition. The verification approach adapts Lauren Tan’s (@poteto) pstack verification-skill generators; attribution and adaptation.