Skip to content

fix(stt): rewrite stale-sidecar voice error + e2e registration guard#1298

Merged
senamakel merged 3 commits intotinyhumansai:mainfrom
obchain:fix/1289-voice-cloud-transcribe-method
May 7, 2026
Merged

fix(stt): rewrite stale-sidecar voice error + e2e registration guard#1298
senamakel merged 3 commits intotinyhumansai:mainfrom
obchain:fix/1289-voice-cloud-transcribe-method

Conversation

@obchain
Copy link
Copy Markdown
Contributor

@obchain obchain commented May 6, 2026

Summary

  • Fixes Voice transcription fails with unknown method openhuman.voice_cloud_transcribe #1289: voice transcription failed with unknown method: openhuman.voice_cloud_transcribe because end users were running a frontend newer than the bundled core sidecar.
  • Pins the controller-registry registration with a JSON-RPC e2e regression guard so this can't recur from a future registry refactor.
  • Surfaces an actionable error from the cloud-STT client when the method really is missing on the running core ("Restart the OpenHuman desktop app to pick up the latest core sidecar").

Problem

The mascot's mic-only composer calls openhuman.voice_cloud_transcribe via app/src/features/human/voice/sttClient.ts. The method is registered correctly in src/openhuman/voice/schemas.rs (added in #1253), wired into the controller registry in src/core/all.rs, and reachable through the dispatcher. So in HEAD the bug is not a missing registration — it's a user-experience gap when the running core sidecar is older than the frontend (auto-update lag, dev build, or staged-binary mismatch). Users got a raw "unknown method: openhuman.voice_cloud_transcribe" with no remediation hint.

There is also no regression coverage that would have caught a future refactor accidentally dropping voice_cloud_transcribe from the registry — every other voice method is in the same boat.

Solution

Two atomic commits:

  1. test(voice): JSON-RPC e2e regression for voice_cloud_transcribe — pin the registration two ways:
    • GET /schema must list openhuman.voice_cloud_transcribe.
    • RPC dispatch on the method must NOT hit the unknown-method branch (Err("unknown method: …")). The call may still fail downstream — that's fine — but the handler must be reachable.
  2. fix(stt): rewrite "unknown method" error with actionable restart hinttranscribeCloud now catches unknown method errors from callCoreRpc and rethrows with a user-facing hint pointing at the desktop app restart, instead of bubbling the raw transport-layer message.

Frontend tests cover both paths (rewrite + verbatim passthrough for unrelated errors). Backend test exercises the full RPC wire path.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per docs/TESTING-STRATEGY.md
  • Diff coverage ≥ 80% — changed lines (Vitest + cargo-llvm-cov merged via diff-cover) meet the gate enforced by .github/workflows/coverage.yml. Run pnpm test:coverage and pnpm test:rust locally; PRs below 80% on changed lines will not merge.
  • N/A: bug fix on existing surface, no new feature row — Coverage matrix updated — added/removed/renamed feature rows in docs/TEST-COVERAGE-MATRIX.md reflect this change
  • N/A: bug fix on existing surface, no new matrix feature ID — All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per docs/TESTING-STRATEGY.md)
  • N/A: doesn't touch release-cut surfaces — Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md)
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Runtime: voice transcription path on desktop only. No schema / RPC signature changes; the method already existed and stays at the same name.
  • Compatibility: additive. Older sidecars still report the same wire-level error; the frontend just rewrites it before showing the user.
  • Performance: zero. Single try/catch around the existing RPC call; no extra round trips.
  • Security: no new attack surface. Error rewrite happens client-side.

Related

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling for cloud voice transcription: when the backend reports an unsupported/unknown method, users now receive a clear, actionable message advising a restart to restore functionality; other errors are propagated unchanged.
  • Tests
    • Added unit tests for transcription error paths (unknown-method vs. other errors).
    • Added an end-to-end test to verify the transcription method is registered and routed correctly.

@obchain obchain requested a review from a team May 6, 2026 12:28
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2a799f9f-e082-4b7e-833a-14fc7e023fe5

📥 Commits

Reviewing files that changed from the base of the PR and between 3769398 and 50712ad.

📒 Files selected for processing (2)
  • app/src/features/human/voice/sttClient.ts
  • tests/json_rpc_e2e.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/json_rpc_e2e.rs
  • app/src/features/human/voice/sttClient.ts

📝 Walkthrough

Walkthrough

This PR guards the transcribeCloud JSON-RPC call, rewriting "unknown method" errors into a user-facing restart message while rethrowing other errors; it adds unit tests for both error paths and an E2E test that verifies the RPC method is present and dispatches without producing an "unknown method" error.

Changes

Voice Transcription Error Handling

Layer / File(s) Summary
Core Error Handling
app/src/features/human/voice/sttClient.ts
Wraps the transcribeCloud RPC call in try/catch, detecting "unknown method" errors and replacing them with a user-facing message advising an app restart; other errors are rethrown unchanged.
Unit Tests
app/src/features/human/voice/sttClient.test.ts
Adds two tests: one verifying "unknown method" RPC failures are rewritten to a restart-app hint, and one verifying non-"unknown method" RPC failures are propagated verbatim.
End-to-End Test
tests/json_rpc_e2e.rs
Adds voice_cloud_transcribe_registered_e2e which asserts the RPC schema exposes openhuman.voice_cloud_transcribe, invokes it, and checks the returned error blob does not contain "unknown method".

Possibly related PRs

  • tinyhumansai/openhuman#1253: Both PRs modify the cloud STT client implementation and RPC wiring for voice transcription; this PR adds error handling and tests around the same transcribeCloud method and RPC registration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through logs and caught the thread,

"unknown method" now gently led;
A friendly hint to restart the app,
So voices sing and errors nap. 🎙️🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing stale-sidecar voice error handling and adding an e2e registration guard.
Linked Issues check ✅ Passed The PR addresses all coding requirements from #1289: rewrites error messaging, adds regression guards, implements passthrough logic, and achieves test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the unknown method error and adding regression safety; no unrelated modifications present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 6, 2026
Copy link
Copy Markdown
Member

@senamakel senamakel left a comment

Choose a reason for hiding this comment

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

there's a merge conflict bro... pls fix it

obchain added 2 commits May 7, 2026 14:11
Pin the registration two ways so issue tinyhumansai#1289's
"unknown method: openhuman.voice_cloud_transcribe" can't recur from
a controller-registry refactor:

1. /schema dump must list the method (frontend discovery).
2. RPC dispatch on the method must NOT hit the unknown-method branch
   — it may still fail downstream on validation/upstream STT, but the
   handler must be reachable.

Refs tinyhumansai#1289.
When an end user runs a frontend newer than the bundled core sidecar
(e.g. dev build, or auto-update lag), `openhuman.voice_cloud_transcribe`
returns a raw "unknown method" error that's opaque to the user.
Catch it in the cloud-STT client and surface a concrete next-step:
"Restart the OpenHuman desktop app to pick up the latest core
sidecar."

Closes tinyhumansai#1289.
@obchain obchain force-pushed the fix/1289-voice-cloud-transcribe-method branch from e4615b6 to 3769398 Compare May 7, 2026 08:44
@obchain
Copy link
Copy Markdown
Contributor Author

obchain commented May 7, 2026

Rebased on latest main — conflict in tests/json_rpc_e2e.rs resolved by appending voice_cloud_transcribe_registered_e2e after the new whatsapp_data_ingest_and_query_e2e. New head 3769398; CI re-running.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/src/features/human/voice/sttClient.ts (1)

66-79: ⚡ Quick win

Add debug logs for both catch branches in transcribeCloud.

The rewritten and passthrough error paths currently drop observability; add sttLog(...) before rethrowing so field debugging can distinguish stale-sidecar rewrites from other RPC failures.

Proposed patch
   } catch (err) {
@@
     const msg = err instanceof Error ? err.message : String(err);
     if (msg.includes('unknown method')) {
+      sttLog('transcribe rpc stale-sidecar path hit; rewriting unknown-method error');
       throw new Error(
         'Voice transcription is unavailable in this build. Restart the OpenHuman desktop app to pick up the latest core sidecar.'
       );
     }
+    sttLog('transcribe rpc failed (passthrough): %O', err);
     throw err;
   }

As per coding guidelines: “Add substantial, development-oriented logs at … error handling paths; use namespaced debug logs in production app code.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/features/human/voice/sttClient.ts` around lines 66 - 79, In
transcribeCloud's catch block (in sttClient.ts) add development-oriented
namespaced logging via sttLog before rethrowing: log a clear message and error
details in the 'unknown method' branch (when msg.includes('unknown method')) and
also log the passthrough/rewritten error path just before throwing err so
callers can distinguish stale-sidecar errors from other RPC failures; reference
the transcribeCloud function and use sttLog(...) with the error object or msg to
preserve observability.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/json_rpc_e2e.rs`:
- Around line 3839-3847: The test currently only checks error.message for the
"unknown method" text which can miss cases where the server puts that text
elsewhere; update the guard to stringify or inspect the entire error object (the
Value at resp.get("error")) and check that the combined error representation
contains "unknown method" (use the existing resp and err_msg variables as
anchors) so the assertion fails if any part of the error object indicates an
unknown-method response.

---

Nitpick comments:
In `@app/src/features/human/voice/sttClient.ts`:
- Around line 66-79: In transcribeCloud's catch block (in sttClient.ts) add
development-oriented namespaced logging via sttLog before rethrowing: log a
clear message and error details in the 'unknown method' branch (when
msg.includes('unknown method')) and also log the passthrough/rewritten error
path just before throwing err so callers can distinguish stale-sidecar errors
from other RPC failures; reference the transcribeCloud function and use
sttLog(...) with the error object or msg to preserve observability.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e34b7aee-a9d8-4c8d-bf1e-9f4e2b02cc35

📥 Commits

Reviewing files that changed from the base of the PR and between e4615b6 and 3769398.

📒 Files selected for processing (3)
  • app/src/features/human/voice/sttClient.test.ts
  • app/src/features/human/voice/sttClient.ts
  • tests/json_rpc_e2e.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/features/human/voice/sttClient.test.ts

Comment thread tests/json_rpc_e2e.rs Outdated
CodeRabbit review on PR tinyhumansai#1298:

- Add `sttLog` calls in both `transcribeCloud` catch arms so field
  debugging can distinguish stale-sidecar rewrites from other RPC
  failures. Per the project's debug-logging policy, error paths get
  namespaced `debug` logs in production app code.
- Harden the regression guard in `voice_cloud_transcribe_registered_e2e`
  to inspect the full `error` object (lowercased) instead of only
  `error.message`. A future server-shape change that moved the
  dispatcher's unknown-method string into `error.data` would otherwise
  silently pass.

Refs tinyhumansai#1289.
@obchain
Copy link
Copy Markdown
Contributor Author

obchain commented May 7, 2026

Conflict cleared on rebase (3769398), then pushed CodeRabbit fixes on top — current head 50712ad. mergeable: true, all 19 checks green. Ready for re-approve when you have a sec.

@obchain obchain requested a review from senamakel May 7, 2026 14:58
@senamakel senamakel merged commit 3bbf4b5 into tinyhumansai:main May 7, 2026
19 of 20 checks passed
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.

Voice transcription fails with unknown method openhuman.voice_cloud_transcribe

2 participants