Skip to content

fix(cli): name the owning Profile when a Session lookup misses - #406

Open
Agnik47 wants to merge 1 commit into
agentrhq:mainfrom
Agnik47:fix/388-session-not-found-owning-profile
Open

fix(cli): name the owning Profile when a Session lookup misses#406
Agnik47 wants to merge 1 commit into
agentrhq:mainfrom
Agnik47:fix/388-session-not-found-owning-profile

Conversation

@Agnik47

@Agnik47 Agnik47 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Fixes #388.

Problem

A Session ID only ever resolves inside the selected Profile, so a command that omits --profile reports Session not found for a Session that plainly exists. The eval runs in the issue show the loop this creates: the agent has a valid ID from session create, drops the flag on the follow-up session close, reads the error as "already gone", and then either retries the identical command or starts inspecting unrelated default Sessions.

session list fed the same confusion from the other side — the rows were always scoped to the selected Profile, but the table never said so, so a list of default Sessions read as the whole machine.

Fix

Every Profile's Sessions live in one browser-sessions.json keyed by profileId, so when the scoped lookup misses, the owning Profile is already in hand — no daemon or provider round trip is needed to name it.

  • SessionNotFoundError takes an optional owner. When known, the message becomes Session not found in Profile <selected>: <id> and the hint names the owner plus the exact retry, webcmd --profile <owner> session close <id>. With no owner the message and hint are byte-for-byte unchanged.
  • Both throw sites are covered: require, and the private requireMutable behind remove / touch / handoff updates — so the close path cannot fall back to the anonymous message.
  • The daemon provider (local-cloak/provider.ts) and the CLI local fallback both resolve through this same store, so one store-level change serves both paths. That also settles the issue's open question about local-only versus daemon lookup: it is local, and it is correct for both.
  • session list gains a profileId table column. JSON and YAML already carried the field; columns only affects table/markdown/csv.
  • docs/troubleshooting.mdx documents the new SESSION_NOT_FOUND behaviour.

Acceptance criteria

  • Closing a Session from the wrong Profile names the owning Profile when known.
  • The retry hint includes webcmd --profile <owner> session close <session-id>.
  • Session list output does not look global when it is Profile-scoped.
  • Agents get a one-step retry instead of a dead end.

Open questions from the issue

  • Should session list without --profile ever show all Profiles? Left scoped, with the scope now visible in the table. Showing every Profile by default is the behaviour the issue calls a safety problem for hosted and multi-tenant use.
  • Local-only or daemon lookup? Local. Both paths share the store, so it is already consistent.
  • Is the skill troubleshooting line still needed? Not addressed here — the CLI error is now explicit, so that line can be revisited separately.

Tests

Three store-level tests (owner named on require, owner named on the mutating path, generic hint preserved when no Profile owns the ID) and one CLI-level test that drives session close without --profile end to end.

155/155 pass across sessions.test.ts, cli.test.ts, and session-docs-sync.test.ts; tsc --noEmit is clean.

Note for reviewers on Windows: the four symlink tests in src/site-memory/local-store.test.ts fail on a clean main in my environment (symlink permissions), unrelated to this change.

Non-goals

No profile create changes, no broad profile cleanup command, and no eval-specific aliases in user-facing text.

A Session ID is only ever resolved inside the selected Profile, so a
command that omits `--profile` reports `Session not found` for a Session
that does exist. Cleanup runs hit this constantly: the agent had a valid
ID from `session create`, dropped the flag on the follow-up
`session close`, read the error as "already gone", and retried the same
command or went inspecting unrelated default-Profile Sessions.

Every Profile's Sessions share one `browser-sessions.json` keyed by
`profileId`, so the owning Profile is already in hand when the scoped
lookup misses — no daemon or provider round trip is needed to name it.
`SessionNotFoundError` now takes an optional owner and, when it is known,
reports which Profile holds the Session plus the exact retry command.
Both throw sites are covered: `require` and the private `requireMutable`
behind `remove`/`touch`/handoff updates. The daemon provider and the CLI
local fallback resolve through this same store, so both paths gain the
hint from the one change. With no owner the message and hint are
unchanged.

`session list` also grows a `profileId` table column. The rows were
always scoped to the selected Profile, but the table did not say so,
which is the other half of how agents ended up acting on Sessions that
were never theirs. JSON and YAML already carried the field.
@github-actions

Copy link
Copy Markdown
Contributor

🟠 Maintainer review suggested — low confidence

The automated review could not reach a fully supported conclusion.

Limitations

  • The automated review returned an invalid structured result.

This review is advisory and does not block merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cli: session commands without --profile should name the owning profile

1 participant