Visitar URL original
fix(server): avoid booting cold locations for pending prompt reads by mlimarenko · Pull Request #53925 · anomalyco/opencode · GitHub
Skip to content

fix(server): avoid booting cold locations for pending prompt reads - #53925

Open
mlimarenko wants to merge 2 commits into
anomalyco:devfrom
mlimarenko:location-recovery
Open

mlimarenko wants to merge 2 commits into
anomalyco:devfrom
mlimarenko:location-recovery

Conversation

@mlimarenko

@mlimarenko mlimarenko commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #53918

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Pending form/permission reads currently acquire a session's full Location graph even when no prompts exist. Add a scoped cached-read operation to the Instance selector and use it for these two lists. A missing cached instance returns an empty list; a warm instance returns its existing prompts.

Host and private SDK selectors each use their own existing cache and sharing key. The read retains that entry until completion, including during invalidation. Session-ID validation, global form placement, active acquisition, and mutations remain unchanged. Intentionally, pending form/permission reads for an existing session whose folder was deleted now return 200 {"data":[]} when its Location is cold; global form reads for a missing cold directory do the same. No Location start is needed to establish that no in-memory prompts exist. LocationNotFoundError can still propagate if an already-starting Location fails while the cached read waits for it. No extra registry or fallback is added.

How did you verify your code works?

The cold-read HTTP regression failed before the fix because it acquired a Location.

After the fix:

  • HTTP prompt/private-instance regressions: 2 tests, 84 assertions passed; 2 affected fetch cases also passed.
  • SDK instance/lifecycle regressions: 9 tests passed.
  • Related Core session/instance/supervisor tests: 56 passed; 16 affected tests passed after the final fixture adjustment.
  • Package typechecks, changed-file formatter/linter checks, and client generation passed; no generated client diff.
  • Native pre-push bun run check: all 36 tasks passed on d7a21e83407624db469fd84f3b9053eb891e1592.

The optional generated-OpenAPI check exposed existing unrelated schema drift, which is not included. Full upstream CI awaits fork-workflow approval and is not claimed green. This fix does not claim to explain the entire reported memory peak.

Screenshots / recordings

Not applicable: server resource-lifecycle behavior, no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. needs:issue labels Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@mlimarenko

Copy link
Copy Markdown
Contributor Author

The native pre-push bun run check passed all 36 tasks on head d7a21e83407624db469fd84f3b9053eb891e1592. GitHub reports the PR as conflict-free. The test, check, and nix-eval workflows currently have action_required; could a maintainer approve these fork workflow runs? Full upstream CI is not claimed green.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@mlimarenko

Copy link
Copy Markdown
Contributor Author

Updated the description to the repository PR template, with Closes #53918 in the required issue section and the verification/checklist sections filled in. Please recheck compliance and the linked issue.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reproduced #53918 from source by restarting the server and then listing a session's permissions or forms. On the base, each call starts the session's location (one location services booted). With this PR, both return {"data":[]} and nothing starts. The changed server, SDK and core tests and the type checks pass. The only failures are three OpenAI OAuth port tests, which also fail on the base.

The approach looks sound. RcMap.getOption only holds an entry that is already running, for the duration of the read. Pending forms and permissions are stored per location, and pending forms are cancelled when it shuts down, so a location that isn't running has nothing to return and [] is correct. Two points, inline: listing for a session whose folder was deleted now returns 200 [] instead of a not-found error, and the new test file is large for what it checks.

return { data: yield* form.list({ sessionID: ctx.params.sessionID }) }
const read = Form.Service.use((form) => form.list({ sessionID: ctx.params.sessionID }))
const forms =
ctx.params.sessionID === "global"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side effect of skipping the location start: a session whose folder has been deleted now gets 200 {"data":[]} from /form and /permission (and from /api/session/global/form with a missing directory) instead of the LocationNotFoundError added in #52668. fetch.test.ts was changed to expect this. Returning an empty list seems reasonable for a read of pending prompts, but please confirm it's intended and mention it in the description. LocationNotFoundError is now listed for session.form.list, but it can only happen if a start already in progress fails.

import { createEmbeddedRoutes } from "../src/routes"
import { cachedLocation } from "../src/location"

it.live(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is 140 lines with its own LocationServiceMap/LayerMap wiring, and it also checks how in-progress reads behave when a location is invalidated. The fetch.test.ts change (loaded() now []) and the SDK configured/setups assertions already cover "no start on a cold read". Could you cut this down to the core case: a cold read returns [] without a lookup, and a running location returns its pending form or permission? Or drop the invalidation half if it doesn't guard a specific bug.

@mlimarenko

mlimarenko commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor Author

Rebased onto current v2 at 7d179e83f42a9bb6377b6f34d8d4fcbf04707621 (package version 2.0.26). New head: 800f6b1d4ebcd798d0855f9b6a2044af231c3922.

Addressed both review points:

  • Yes, a pending-prompt read for an existing session whose folder was deleted intentionally returns 200 {"data":[]} when the Location is cold. Global form reads for missing cold directories do the same. The description now states this explicitly; session-ID validation and active mutations remain unchanged. LocationNotFoundError remains possible when an already-starting cached Location fails.
  • Removed the invalidation/lifetime half of session-prompts.test.ts and its finalizer wiring/imports. The focused HTTP test retains the cold no-lookup case, unknown-session errors, and warm pending form/permission/global-form reads. No production semantics changed; the original implementation commit is unchanged according to git range-diff.

Focused checks passed: 1 prompt-read test, 2 affected fetch tests, 6 SDK instance/lifecycle tests, and 1 private-session-instance test. Changed-file Prettier and git diff --check passed. The native pre-push bun run check passed all 36 tasks, and the lease-protected push completed successfully.

A broader fetch-file run had 10 passes and 3 OpenAI OAuth callback failures (timeout/port 1455 in use), matching the unrelated failures already noted in the review. It is not claimed green. Full upstream CI is also not claimed green; fork workflows may require maintainer approval. The description still references Closes #53918.

Base clarification: release commit 9b4ec5714d481559990db0a816d5dec19541a814 is a sibling of the current development line, not its ancestor; these PRs target and are rebased onto upstream/v2 as requested.

@thdxr
thdxr changed the base branch from v2 to dev October 10, 2026 19:36

This branch has not been deployed

No deployments
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.

V2: pending form and permission reads bootstrap idle session locations

2 participants