fix: hand the jobs registry a session id, not the agent handle
Release / release (push) Successful in 6s

JobSpec.owner is a SessionId, and the registry resolves it through
agents.get(owner) - so passing exec.agent made the DEFAULT index call fail
with 'session "[object Object]" has no live agent'. Since index defaults to
run_in_background, the action that exists to pre-index a workspace was the
one action that could not run. A handle without an id registers the job
unowned rather than throwing.

The test mounts a jobs service and pins the owner contract; no test had ever
supplied one, which is why this reached a real deployment.
This commit is contained in:
NotExpectedYet committed 2026-09-27 07:16:31 +01:00
1 parent de4d020dcb
commit 0dc79f8e0b
1 file changed
+12 -1
+12 -1
View File
@@ -1356,10 +1356,21 @@ export function apply(ctx, config) {
)
if (wantsBackground && jobs !== undefined) {
// `owner` is a SESSION ID, not the Agent handle.
//
// The jobs registry resolves an owner through the agent registry —
// `agents.get(session)` — and throws `session "[object Object]" has
// no live agent` for anything else, so passing `exec.agent` here made
// the default `index` call fail outright: it is the one path this
// plugin takes that a caller cannot see fail until the job service is
// present. The agent's own `id` IS the session id (the registry keys
// by it), and a handle without one is registered unowned rather than
// refused.
const owner = exec.agent?.id
const jobId = jobs.start({
kind: 'recall-index',
label: `recall index ${workspace}`,
...(exec.agent === undefined ? {} : { owner: exec.agent }),
...(owner === undefined || owner === null || owner === '' ? {} : { owner }),
run: () => {
const controller = new AbortController()
const done = (async () => {