Skip to content

fix(pi): stop blank input placeholders from failing the run - #23235

Open
only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:r13/a081-use-the-dialog-title-when-its-placeholde
Open

only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:r13/a081-use-the-dialog-title-when-its-placeholde

Conversation

@only21mil

Copy link
Copy Markdown
Contributor

Problem

A Pi extension that asks for free text with a blank placeholder fails the whole run. @juicesharp/rpiv-ask-user-question does this: picking its "Type something." option opens an input dialog with an empty placeholder. The thread shows "Provider turn failed." while Pi keeps waiting on the dialog, and the next message fails with "the previous turn is still running" (#22405).

The cause is in piQuestion. It builds the question with message ?? placeholder ?? title. ?? keeps empty strings, so placeholder: "" becomes the question. The user input contract requires a non-blank question, so ingesting the user_input_request item fails and the run fails with it.

Change

piQuestion now uses the first of message and placeholder that has non-whitespace text, and falls back to the title otherwise. A dialog with a real placeholder, or with none, behaves as before.

Scope and approval

Fixes the field that fails validation in #22405. Julius triaged it on Linux, left it open, and noted that verifying it needs Pi with the question extension configured. The real-app run below uses Pi with a local extension that sends the same dialog.

This PR fixes the bad event only. It does not touch the issue's second point, where building ProviderEventNormalizeError throws instead of returning a typed error. #23169 separately recovers a thread after any ingestion failure; the two do not overlap.

Verification

  • Regression test in adapter.test.ts: a real extension_ui_request with method: "input", a multiline title and placeholder: "". It decodes the questions through the OrchestrationV2UserInputQuestion contract, checks the question is the title, and checks Pi gets the exact answer.
    • With main's adapter.ts: fails with SchemaError: Expected a non-blank string at [0]["question"].
    • On this branch: passes.
  • adapter.test.ts in full: 84 passed.
  • Typecheck (tsc-rs --noEmit), lint and format check: all exit 0.
cd packages/provider-pi
pnpm exec vp test run --config ../../vite.config.ts --dir . src/server/adapter.test.ts -t "asks an input dialog's title when its placeholder is blank"
pnpm exec vp test run --config ../../vite.config.ts --dir . src/server/adapter.test.ts
pnpm run typecheck
cd ../..
pnpm exec vp lint --report-unused-disable-directives packages/provider-pi/src/server/adapter.ts packages/provider-pi/src/server/adapter.test.ts
pnpm exec vp fmt --check packages/provider-pi/src/server/adapter.ts packages/provider-pi/src/server/adapter.test.ts

Real app, production builds of main and this branch on Linux, with the real Pi 1.3.0 CLI, a local chat-completions stub instead of a model, and a small personal Pi extension whose tool calls ctx.ui.input with a five-line title and "" as the placeholder.

  • Main: after the tool opens the dialog, the thread shows "Provider turn failed." and no question card, while the status line still says it is waiting on ask_text. The server logs "provider event ingestion failed" with "Schema validation failed". Sending "hello" then fails with "the previous turn is still running". This matches Pi run fails with "Provider turn failed." when a question's "Type something" option opens a follow-up input dialog #22405.
  • This branch: the question card shows the multiline title. A typed answer reaches the extension unchanged (answer: SQLite with WAL), the turn finishes, and a second ask in the same thread works. Picking "Submit empty value" also finishes the turn with an empty answer. The server logs no ingestion failure.

Main, after the dialog opens and a follow-up message:

Main: Provider turn failed, then the previous turn is still running

This branch, the question card with a typed answer before Submit:

Branch: the question card shows the title and the composer holds a typed answer

This branch, after Submit (the first turn used "Submit empty value"):

Branch: both turns finish and the tool gets the typed answer

The regression test on main and on this branch:

Test fails on main with the non-blank question error

Test passes on this branch

Not checked: the published rpiv-ask-user-question extension itself, a real model, desktop and mobile clients, macOS and Windows.

Prior PRs: none attempted this fix. #21762 fixed the same kind of failure for blank select options in this function, and the new test follows its pattern. Thanks to @TheAsda for the detailed report in #22405, which named the input dialog and its empty placeholder. My open #22463 changes the header in the same function for titles shown twice, and the two conflict in adapter.ts. This PR should land first, since it fixes a failed run and #22463 only changes what the card shows. #22463 then rebases so its detail text takes the first non-blank message or placeholder.

Production fix, tests, PR description and images written with Claude Opus 5.5 in T3 Code Nightly.

🤖 Generated with Claude Opus 5.5 in T3 Code Nightly

An input dialog with placeholder "" produced an empty question, which
fails the user input contract and fails the run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 22, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6163ead

Macroscope's review found this PR approvable — This is a narrowly scoped Pi adapter bug fix that falls back from blank input text to the dialog title, preserving existing nonblank behavior and response handling. A focused regression test covers the affected path, with no product-default or static-analysis configuration changes.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 66e275fd-a3f6-4f72-8660-e9ff81e884b5
📥 Commits

Reviewing files that changed from the base of the PR and between f8e4834 and 6163ead.

📒 Files selected for processing: 2
  • packages/provider-pi/src/server/adapter.test.ts
  • packages/provider-pi/src/server/adapter.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

📝 Walkthrough

Pi input dialogs now use the first nonblank message or placeholder as the question, falling back to the title. A test checks the title fallback and verifies that the submitted answer appears in the extension UI response.

Changes: Pi input question fallback

Layer / File(s) Summary
Question selection and response test
packages/provider-pi/src/server/adapter.ts, packages/provider-pi/src/server/adapter.test.ts
piQuestion skips blank message and placeholder values and falls back to the title. The test submits an answer and checks the extension UI response.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Low

Possibly related issues

  • pingdotgg/t3code#22405 — The issue reports a Pi follow-up input dialog failure with a blank placeholder. This change falls back to the title when the placeholder and message are blank.

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 6163e

Blank-placeholder dialogs are intended to use the title as the question while preserving the submitted answer, and the supplied test summary covers that path. No concrete merge-blocking risk is established; broader platform and real-model runs were not reported.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the Pi fix for blank input placeholders that cause runs to fail.
Description check Passed The description includes complete Problem, Change, Scope and approval, and Verification sections. It explains the root cause, links the related issue, documents focused tests and real-app verification…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description includes complete Problem, Change, Scope and approval, and Verification sections. It explains the root cause, links the related issue, documents focused tests and real-app verification, identifies untested environments, and includes required UI evidence and agent attribution.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

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

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant