vercel / vercel/eve

Freeform reply to an options-only question is silently deferred forever — session goes mute (question-kind sibling of #1224)

Open
#1,908 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug core p1
Dominant language
TypeScript
Stars
5.3k
Forks
569
Avg merge
21h 56m
Merged PRs (30d)
531

Description

Summary

When the harness is waiting on a kind: "question" input request that has options but no allowFreeform, a freeform text reply that does not match any option id/label/index produces zero input responses and the message is parked in deferredStepInput forever. The turn ends silently, the question stays pending, and the session goes mute — every subsequent message defers again.

This is the question-kind sibling of #1224 (which covers the same silent-defer path for tool approvals). #888 resolved freeform text only for questions that allow freeform; an options-only question still cannot be resolved by text.

Verified on eve@0.29.4.

Mechanism

In dist/src/channel/resolve-text.js, resolveTextToResponse returns undefined when the request has options, the text matches no option id/label/1-based index, and allowFreeform !== true:

if ((t.allowFreeform === !0 || t.options === void 0 || t.options.length === 0) && n.length > 0)
  return { requestId: t.requestId, text: n };
// otherwise: undefined — no response is produced

Then in dist/src/harness/input-requests.js (resolvePendingInput), the batch still has an unanswered required request, so the input is queued as deferred and the turn ends with no output:

if (hasUnansweredRequiredRequest({ pendingBatch: a, responses: s }))
  return n = queueDeferredStepInput(n, compactStepInput(o)),
    { deferredMessage: !0, outcome: `unresolved`, messages: r, session: n };

Nothing is emitted to the channel, so the user gets no feedback that their reply was not accepted.

How we hit it (production hang)

Our root agent delegated to a subagent, which called ask_question with two options and no freeform. The request was proxied to the parent's channel (Linear Agent Session) via the subagent HITL proxy. The user replied with freeform text ("analyze both, one by one"), which matched neither option:

  • the reply produced no inputResponses, so routeDeliverPayload had nothing to route to the parked child;
  • the message was deferred; no model turn resumed; a second user message 17 minutes later deferred as well;
  • both the child and the parent session stayed parked indefinitely (run wrun_41KZNG1WDR0GKW8B3MFH11XCWK, last activity 2026-08-10T11:31Z, no completion).

The subagent proxy is not required for the bug — the silent defer happens in resolvePendingInput either way — but it makes the failure worse: the human-facing channel shows a question, the human answers in prose, and the whole delegation tree hangs.

Repro
  1. Have the model call ask_question with options: [a, b] and no allowFreeform (directly, or from a subagent so the request is proxied to the parent channel).
  2. Reply with freeform text that is not an option id, label, or index.
  3. The turn ends silently; the question stays pending; the session never responds again.
Expected

Some non-silent outcome, e.g. one of:

  • treat the freeform text as a text response even for options-only questions (the model can re-ask if the text is unusable), or
  • reject the reply visibly on the channel ("please pick one of the options") while keeping the question pending, or
  • resolve the question as unanswered and hand the text to the model as new user context (mirroring what #1224 proposes for approvals).

Anything but silently deferring the message with no feedback and no way to make progress.

Refs: #1224 (approvals variant, open), #785 / #888 (stale HITL responses), #568 (subagent input-request bubbling).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in dist/src/channel/resolve-text.js at resolveTextToResponse, then trace the result into dist/src/harness/input-requests.js at resolvePendingInput and queueDeferredStepInput. Reproduce an options-only question followed by unmatched freeform text, and determine the intended visible outcome. Done means the reply no longer disappears into deferredStepInput without feedback or progress, while valid option replies continue to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.