Skip to content

fix(observability): classify OpenHuman/Embedding/streaming backend 'Invalid token' 401 as SessionExpired (TAURI-RUST-4P0 + 4K5 + 1EE)#2786

Merged
graycyrus merged 3 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/observability-openhuman-invalid-token
May 28, 2026
Merged

fix(observability): classify OpenHuman/Embedding/streaming backend 'Invalid token' 401 as SessionExpired (TAURI-RUST-4P0 + 4K5 + 1EE)#2786
graycyrus merged 3 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/observability-openhuman-invalid-token

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 27, 2026

Summary

Extend is_session_expired_message in src/core/observability.rs to recognise the OpenHuman backend's {"success":false,"error":"Invalid token"} 401 envelope as a session-expired condition (previously only the explicit "Session expired. Please log in again." body was recognised). The same upstream cause — backend rejecting the bearer JWT as invalid — surfaces under three emit-site prefixes depending on the call path, each producing its own Sentry fingerprint:

Sentry ID Emit-site prefix Source Events
TAURI-RUST-4P0 OpenHuman API error (401 …) non-streaming chat (run_chat_task)
TAURI-RUST-4K5 Embedding API error (401 …) embeddings/openai.rs:139 ~118
TAURI-RUST-1EE OpenHuman streaming API error (401 …) streaming chat (compatible.rs:949) ~110

All three are typically preceded by a [scheduler_gate] signed_out false -> true breadcrumb. The UI already drives reauth via the SessionExpired event-domain path; this stops the noise leaking into Sentry as a code bug.

Why three arms, not one

The matcher uses conjunctive anchors per arm — "<emit-site prefix> (401" AND the envelope-shaped "\"error\":\"Invalid token\"". Anchoring on each OpenHuman-scoped prefix is what preserves the #2286 BYO-key contract:

  • "OpenAI API error (401 Unauthorized): invalid_api_key" (user's own OpenAI key revoked) must NOT match.
  • "OpenAI streaming API error (401): invalid_api_key" and "Embedding API error (401): invalid_api_key" (BYO embedding/streaming key revoked) must NOT match either.

Each of those is pinned by a dedicated does_not_classify_*_byo_key_401_as_session_expired polarity guard. A single broad "any 401 + invalid token" matcher would silence all of them, so each OpenHuman-backend emit-site prefix gets its own prefix-gated arm. The streaming token in 1EE specifically means the 4P0 anchor can't cover it.

Tests added (observability::tests)

  • classifies_openhuman_invalid_token_401_as_session_expired — 4P0 (wrapped + unwrapped).
  • classifies_embedding_api_invalid_token_401_as_session_expired — 4K5 (direct + wrapped).
  • classifies_openhuman_streaming_invalid_token_401_as_session_expired — 1EE (direct + wrapped).
  • does_not_classify_embedding_byo_key_401_as_session_expired — embedding polarity guard.
  • does_not_classify_streaming_byo_key_401_as_session_expired — streaming polarity guard.
  • Existing does_not_classify_byo_key_provider_401_as_session_expiredSessionExpired clears the session for unrelated backend 401s #2286 chat-path contract, still green.

Test plan

  • cargo test classifies_openhuman_invalid_token — passes (4P0)
  • cargo test classifies_embedding_api_invalid_token — passes (4K5)
  • cargo test classifies_openhuman_streaming_invalid_token — passes (1EE)
  • cargo test does_not_classify_embedding_byo_key / does_not_classify_streaming_byo_key / does_not_classify_byo_key_provider — pass (polarity)
  • cargo test core::observability — 93 tests pass, 0 regressions
  • cargo check --bin openhuman-core — passes
  • cargo fmt --check — clean

Related

Self-hosted Sentry (sentry.tinyhumans.ai, tauri-rust project) — no GitHub issue:

Closes TAURI-RUST-4P0
Closes TAURI-RUST-4K5
Closes TAURI-RUST-1EE

… SessionExpired

The OpenHuman backend rejects an expired/revoked JWT with the envelope
`{"success":false,"error":"Invalid token"}` (vs. the explicit
`"Session expired. Please log in again."` body that the existing
classifier already catches). Same emit site
(`providers::ops::api_error` → `web_channel.run_chat_task`), same
wrapping, same expected user state — just a different body substring
chosen by the backend's JWT-validity branch.

Issue tinyhumansai#2286 deliberately stopped matching bare `"Invalid token"` as
session-expired because that string also surfaces from Discord /
OAuth provider rejections, which are actionable scoped errors that
must reach Sentry. We preserve that contract with a conjunctive
matcher: BOTH the OpenHuman-scoped `"OpenHuman API error (401"`
prefix AND the envelope-shaped `"\"error\":\"Invalid token\""` must
be present.

tinyhumansai#2286 cases still route to Sentry (verified by the existing
`does_not_classify_byo_key_provider_401_as_session_expired` test
staying green):

- `"Invalid token"`                                   → None ✓
- `"got an invalid token here"`                       → None ✓
- `"OpenAI API error (401 Unauthorized): invalid_api_key"`  → None ✓
- `"Anthropic API error (401 Unauthorized): ..."`     → None ✓

Targets Sentry OPENHUMAN-TAURI-4P0 (issue 5332): low volume so far
(1 event) but the wire shape is durable — every OpenHuman user with
a stale JWT will hit this on the next agent turn, so quietly
demoting it to a `warn!` log keeps the noise from compounding.
@CodeGhost21 CodeGhost21 requested a review from a team May 27, 2026 20:16
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

Adds conjunctive matching and docs in is_session_expired_message to classify OpenHuman/Embedding 401 "Invalid token" JSON envelopes as SessionExpired, and adds regression tests covering wrapped/unwrapped and negative BYO-key cases.

Changes

OpenHuman 401 Invalid Token Classification

Layer / File(s) Summary
Session-expired classification for OpenHuman 401 invalid-token
src/core/observability.rs
Doc comment expanded to describe the OpenHuman 401 {"error":"Invalid token"} envelope and the embedding wrapper; is_session_expired_message updated to conjunctively require the "OpenHuman API error (401" or "Embedding API error (401" prefix plus the exact invalid-token envelope before returning ExpectedErrorKind::SessionExpired.
Regression tests for invalid-token classification
src/core/observability.rs
New tests assert both wrapped run_chat_task and unwrapped OpenHuman invalid-token envelopes classify as SessionExpired; verify embedding invalid-token wrapper classifies as SessionExpired; and guard that BYO-key/generic 401 variants do not classify as session-expired.

Sequence Diagram(s)

(omitted — change is a targeted classifier update and tests; no multi-component sequential flow requires visualization)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • senamakel
  • graycyrus
  • M3gA-Mind

Poem

🐰 A token slipped out of date and key,
The 401 whispered, "Invalid token" to me.
I matched prefix and envelope with care,
So sessions expire only when they truly bear.
Hooray — tests hop in, the classifier set free!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
Title check ✅ Passed The title directly summarizes the main change: classifying OpenHuman/Embedding invalid token 401 responses as SessionExpired, which is the primary purpose of the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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


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

@coderabbitai coderabbitai Bot added working A PR that is being worked on by the team. bug labels May 27, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 27, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

@CodeGhost21 hey! the code looks good to me — the conjunctive anchor approach is exactly right here. Requiring both the "OpenHuman API error (401" prefix and the envelope-shaped "\"error\":\"Invalid token\"" body together is the correct way to preserve the #2286 contract while catching this specific backend branch, and the two new test cases pin both the verbatim Sentry wire shape and the unwrapped emit shape cleanly.

CI still has a few checks pending (Windows E2E, core image build, Rust core coverage). Once those come back green I'll come back and approve this. Let me know if anything comes up in the meantime.

…sionExpired (TAURI-RUST-4K5)

TAURI-RUST-4K5 (~118 events, escalating on 0.56.0,
domain=embeddings operation=openai_embed status=401) carries the same
OpenHuman backend `{"success":false,"error":"Invalid token"}` envelope
as 4P0, but the embedding client at
`src/openhuman/embeddings/openai.rs:139` wraps it with the
`"Embedding API error"` prefix instead of `"OpenHuman API error"`. The
breadcrumb `[scheduler_gate] signed_out false -> true` immediately
preceding the 401 in the event payload confirms it's the same
session-expired cause, just emitted at the embedding layer.

The conjunctive `"OpenHuman API error (401"` anchor added in the
previous commit catches the chat-API path; this commit adds a parallel
`"Embedding API error (401"` anchor so the embedding path also routes
to SessionExpired. The envelope-shaped `"\"error\":\"Invalid token\""`
gate stays the same, so third-party BYO-key embedding 401s (OpenAI /
Voyage / Cohere rejecting the user's own API key) continue to escalate
as actionable misconfiguration — covered by the new
`does_not_classify_embedding_byo_key_401_as_session_expired`
polarity guard.

## Test plan
- [x] `cargo test classifies_embedding_api_invalid_token` — passes (new)
- [x] `cargo test does_not_classify_embedding_byo_key` — passes (new polarity guard)
- [x] `cargo test classifies_openhuman_invalid_token` — passes (4P0, unchanged)
- [x] `cargo test does_not_classify_byo_key_provider` — passes (tinyhumansai#2286 BYO-key contract preserved)
- [x] `cargo test core::observability` — 91 tests pass, 0 regressions
- [x] `cargo check --bin openhuman-core` — passes
- [x] `cargo fmt --check` — clean
@CodeGhost21 CodeGhost21 changed the title fix(observability): classify OpenHuman backend 'Invalid token' 401 as SessionExpired fix(observability): classify OpenHuman/Embedding backend 'Invalid token' 401 as SessionExpired (TAURI-RUST-4P0 + 4K5) May 27, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 27, 2026
…as SessionExpired (TAURI-RUST-1EE)

Third emit-site prefix for the same OpenHuman backend
`{"success":false,"error":"Invalid token"}` 401 envelope this PR
already classifies for non-streaming chat (4P0) and embeddings (4K5).

TAURI-RUST-1EE (Sentry issue 1807, 110 events, 109 on
openhuman@0.56.0, domain=llm_provider operation=streaming_chat
status=401 provider=OpenHuman) is the streaming-chat path: the body is
wrapped at `inference/provider/compatible.rs:949` with the
`"OpenHuman streaming API error"` prefix. The `streaming` token between
`OpenHuman` and `API error` means the 4P0 anchor
(`"OpenHuman API error (401"`) does not match it, so it needs its own
prefix arm.

Same conjunctive-anchor pattern as the existing arms — the
OpenHuman-scoped streaming prefix gates the match so a third-party
BYO-key streaming 401 (`"OpenAI streaming API error (401):
invalid_api_key"`) stays actionable in Sentry.

Tests:
- `classifies_openhuman_streaming_invalid_token_401_as_session_expired`
  — verbatim 1EE wire shape (direct + caller-wrapped).
- `does_not_classify_streaming_byo_key_401_as_session_expired` —
  polarity guard for the streaming prefix.

## Test plan
- [x] `cargo test classifies_openhuman_streaming_invalid_token` — passes
- [x] `cargo test does_not_classify_streaming_byo_key` — passes (polarity)
- [x] `cargo test core::observability` — 93 tests pass, 0 regressions
- [x] `cargo check --bin openhuman-core` — passes
- [x] `cargo fmt --check` — clean
@CodeGhost21 CodeGhost21 changed the title fix(observability): classify OpenHuman/Embedding backend 'Invalid token' 401 as SessionExpired (TAURI-RUST-4P0 + 4K5) fix(observability): classify OpenHuman/Embedding/streaming backend 'Invalid token' 401 as SessionExpired (TAURI-RUST-4P0 + 4K5 + 1EE) May 28, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

@CodeGhost21 the two follow-on commits look clean — the 4K5 (Embedding API) and 1EE (streaming) arms follow the same conjunctive-anchor pattern as the original 4P0 arm, the polarity guards for BYO-key embedding and streaming 401s are solid, and the test coverage (direct + caller-wrapped shapes for each arm) is thorough.

One CI check is still pending (Windows / Appium Chromium E2E). Once that clears, I'll come back and approve this.

@oxoxDev oxoxDev assigned oxoxDev and unassigned oxoxDev May 28, 2026
oxoxDev pushed a commit to CodeGhost21/openhuman that referenced this pull request May 28, 2026
`reliable::format_failure_aggregate` (no-configured-fallbacks branch)
wraps every exhausted `reliable_chat_with_system` turn with:

  "The model `<name>` may not be available on your provider.
   Configure a fallback chain via `reliability.model_fallbacks` in
   your OpenHuman config, or change your default model in Settings
   → AI.\n\nAll providers/models failed. Attempts:\n…"

The aggregate fires once per turn regardless of the underlying per-
attempt cause (401 auth wall, unknown model, region block, rate-
limit cliff). All of those are user-actionable: pick a different
model, fix the credential, or configure fallbacks — the message
literally tells the user how. Sentry has no remediation path that
the per-attempt body classifiers haven't already covered at the
lower layer (`SessionExpired`, `BudgetExhausted`, config_rejection
siblings, etc.).

Adds `"reliability.model_fallbacks"` to the
`is_provider_config_rejection_message` PHRASES list. The string is
uniquely OpenHuman — that config path is rendered into an error
message only from `reliable.rs:332-334`, verified via grep across
`src/`. A stray "may not be available" log line elsewhere will not
collide. The configured-fallbacks aggregate branch (just
`"All providers/models failed. Attempts:\n…"`) is intentionally
NOT matched — the user has already engaged with the knob, so per-
attempt classifiers should drive the per-body decision.

Targets Sentry OPENHUMAN-TAURI-4JS (issue 5215): 25 events on
v0.56.0 in 5h, `domain=llm_provider operation=reliable_chat_with_system
failure=all_exhausted`. The current 25-event sample carries an
"Invalid token" 401 underlying cause (body-equivalent to the
already-open PR tinyhumansai#2786, which would also demote this aggregate via
the body substring match). This PR catches the aggregate at the
emit-site level so future all_exhausted scenarios with non-401
underlying causes (model name typo, region block, …) demote the
same way.

Tests pin the verbatim 4JS payload + three underlying-cause variants
(unknown-model upstream, region block, bare aggregate) + a negative
guard confirming the configured-fallbacks branch does NOT classify on
the aggregate phrase alone.
@oxoxDev oxoxDev self-requested a review May 28, 2026 18:08
Copy link
Copy Markdown
Contributor

@oxoxDev oxoxDev left a comment

Choose a reason for hiding this comment

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

Walkthrough

Extends is_session_expired_message in src/core/observability.rs with 3 new conjunctive-anchor arms — each gating on a distinct emit-site prefix ("OpenHuman API error (401" / "Embedding API error (401" / "OpenHuman streaming API error (401") AND the envelope-shaped "\"error\":\"Invalid token\"". Drops self-hosted Sentry issues TAURI-RUST-4P0 (non-streaming chat) + 4K5 (~118 events, embedding openai.rs:139) + 1EE (~110 events, streaming compatible.rs:949). +209/-0, 1 file. 5 new tests. All CI green.

Verified

  • Three-prefix split is real: "streaming" token between OpenHuman and API error breaks the 4P0 anchor on 1EE, so each path genuinely needs its own arm — confirmed in author doc + test ✓
  • Polarity arithmetic: BYO 401s carry invalid_api_key / authentication_error payloads — they hit the prefix anchor but the envelope anchor "error":"Invalid token" fails → no match → still reach Sentry. Confirmed for OpenAI/Anthropic/Voyage/Cohere shapes ✓
  • Pre-existing does_not_classify_byo_key_provider_401_as_session_expired (#2286 contract) still in place; both new polarity guards (embedding + streaming BYO) extend the same contract per emit-site ✓
  • Wire-shape envelope tolerant of optional whitespace: {"success":false,"error":"Invalid token"} and {"success":false, "error":"Invalid token"} both substring-match "error":"Invalid token"

Nits

  • The 3 arms share the same (<prefix> && envelope) shape. When a 4th emit-site (e.g. tool-call backend, embeddings rerank path) lands, worth hoisting to a small &[(prefix, envelope)] table + .iter().any(...) so each new arm is one tuple line, not 4 lines of boilerplate. Don't block on it.
  • Envelope match is case-sensitive on "Invalid token". If backend ever swaps to INVALID_TOKEN / camelCase / etc., these arms silently fall through. Cheap defense: anchor on the lowercase variant via lower.contains(...) like the existing arms above. Worth a follow-up.
  • User-pasted JSON in chat that contains exactly OpenHuman API error (401 + "error":"Invalid token" would get silenced. Vanishingly unlikely (the prefix is emit-site-only string), but the prefix-as-gate is the only guard. Flagging only.

Questions

  • Did you check whether the expected_error_kind dispatch path that calls is_session_expired_message produces an ExpectedErrorKind::SessionExpired with the same Breadcrumb-vs-Ignore tier as the existing arms? (Want to make sure the new shapes drop to Ignore at TRACE / DEBUG vs Breadcrumb at INFO/WARN — leak risk per feedback_devtools_smoke_void_promise style breadcrumbs-stick-to-events pattern.)
  • Self-hosted Sentry — confirm Closes TAURI-RUST-4P0, Closes TAURI-RUST-4K5, Closes TAURI-RUST-1EE are in the PR body so Phase 7 Step 4.5 self-hosted sweep flips them on merge.

@CodeGhost21
Copy link
Copy Markdown
Contributor Author

@oxoxDev thanks for the thorough review and the approval! Answering your two questions:

Q1 — tier / breadcrumb-leak risk. No divergence: classification routes on the kind, not the message shape. is_session_expired_messageexpected_error_kind returns Some(ExpectedErrorKind::SessionExpired), and report_expected_message funnels every SessionExpired through the single match arm at src/core/observability.rs:1064, which deliberately demotes to tracing::info! ("breadcrumb survives for trace correlation but Sentry sees no error event"). All three new arms (4P0/4K5/1EE) inherit that exact treatment — there is no per-shape tier branch, so the new shapes can't drop to a different Breadcrumb/Ignore level than the existing arms. No leak risk introduced beyond the already-accepted SessionExpired behavior.

Q2 — self-hosted Sentry close directives. Added to the PR body under a new ## Related section:

Closes TAURI-RUST-4P0
Closes TAURI-RUST-4K5
Closes TAURI-RUST-1EE

One heads-up for the Phase 7 Step 4.5 sweep: PR #2692's body flagged that the post-merge resolve regex is anchored to OPENHUMAN-(TAURI|REACT|CORE) and may not match the bare TAURI-RUST-* prefix yet. If that widening hasn't landed, these may need a manual flip on merge.

Nits — all noted as follow-ups (not in this PR): the &[(prefix, envelope)] table hoist when a 4th emit-site lands, case-insensitive "invalid token" matching, and the user-paste edge case. Agreed they're worth a follow-up but not blockers here.

@graycyrus graycyrus merged commit 14ff92b into tinyhumansai:main May 28, 2026
43 of 44 checks passed
sanil-23 added a commit to sanil-23/openhuman that referenced this pull request May 28, 2026
…adiction on Embedding 401 + Invalid token

PRs tinyhumansai#2830 and tinyhumansai#2786 both shipped on main and made contradictory assertions
for the SAME wire shape:

    Embedding API error (401 Unauthorized): {"success":false,"error":"Invalid token"}

- tinyhumansai#2830 added `is_embedding_backend_auth_failure` and a test asserting
  `BackendUserError`.
- tinyhumansai#2786 added `classifies_embedding_api_invalid_token_401_as_session_expired`
  asserting `SessionExpired`.

The tinyhumansai#2830 arm runs first in `expected_error_kind`, so the tinyhumansai#2786 test fails
in CI on every PR that rebases onto current main (verified on
upstream/main @ e83bfd6).

Per the doc evidence and breadcrumb context (`[scheduler_gate] signed_out
false -> true` immediately preceding the 401), the SessionExpired routing
is the correct one — the OpenHuman backend envelope `{"success":false,
"error":"Invalid token"}` is the JWT-invalidity branch of the same
session-renewal flow as TAURI-RUST-4P0.

Disable `is_embedding_backend_auth_failure` (keep the function as a doc
breadcrumb so the regression is traceable) and remove the contradicting
`classifies_embedding_backend_auth_failure` test. The SessionExpired arm
in `is_session_expired_message` (added by tinyhumansai#2786) now catches the wire
shape correctly. BYO-key embedding 401s (no OpenHuman envelope) still
escalate to Sentry — guarded by
`does_not_classify_embedding_byo_key_401_as_session_expired`.

Local tests: cargo test core::observability::tests → 117/117 pass.
Local repro: `classifies_embedding_api_invalid_token_401_as_session_expired`
panicked on pure upstream/main before this commit; passes after.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sanil-23 added a commit to sanil-23/openhuman that referenced this pull request May 28, 2026
…sionExpired (TAURI-RUST-4K5 regression)

PR tinyhumansai#2786 (commit 14ff92b) added an `is_embedding_backend_auth_failure`
matcher that was supposed to classify the TAURI-RUST-4K5 wire shape
(`Embedding API error (401 Unauthorized): {"error":"Invalid token"}`)
as `SessionExpired` — to align with the 4P0 OpenHuman-backend variant
and surface a re-login prompt instead of a Sentry noise bucket.

A subsequent merge (tinyhumansai#2830 commit d578b57, 'demote expected-error
Sentry buckets across embeddings, provider, memory-store, FS, and
thinking-mode wire shapes') landed on a pre-tinyhumansai#2786 base and clobbered
the SessionExpired return back to BackendUserError. The
`classifies_embedding_api_invalid_token_401_as_session_expired` test
that tinyhumansai#2786 shipped therefore fails on every PR rebased onto current
`upstream/main`:

  assertion `left == right` failed:
    TAURI-RUST-4K5 verbatim wire shape must classify as SessionExpired
    left:  Some(BackendUserError)
    right: Some(SessionExpired)

Restore the intended return value. One-line fix to the
`is_embedding_backend_auth_failure` arm in `expected_error_kind`.
All observability tests pass.

Co-Authored-By: Claude <noreply@anthropic.com>
@sanil-23
Copy link
Copy Markdown
Contributor

Posted #2869 with the root-cause fix: #2830's merge inadvertently reverted #2786's SessionExpired classification back to BackendUserError, so the classifies_embedding_api_invalid_token_401_as_session_expired test added by #2786 has been failing on every PR rebased onto post-#2830 main. One-line classifier fix + reconciled the stale companion test.

CodeGhost21 added a commit to CodeGhost21/openhuman that referenced this pull request May 28, 2026
… so embedding 401 'Invalid token' classifies as SessionExpired (TAURI-RUST-4K5)

The merge surfaced a pre-existing main contradiction (tinyhumansai#2786 vs tinyhumansai#2830): the
embedding 401 "Invalid token" envelope was shadowed by the broader
is_embedding_backend_auth_failure matcher (BackendUserError) before reaching
is_session_expired_message. Move the narrowly-anchored session-expired check
ahead of the embedding-auth matcher so the parenthesised
`Embedding API error (401 …): {"error":"Invalid token"}` shape classifies as
SessionExpired; the bare-status shape still falls through to BackendUserError.
Mirrors the authoritative fix in tinyhumansai#2867 to unblock this PR's Rust Core Tests.
sanil-23 added a commit to Sathvik-1007/openhuman that referenced this pull request May 28, 2026
…ssionExpired

The TAURI-RUST-4K5 wire-shape (`Embedding API error (401 Unauthorized):
{"success":false,"error":"Invalid token"}`) is the OpenHuman backend's
session-expired envelope reaching the embeddings worker, not a backend
4xx bug. PR tinyhumansai#2786 added a SessionExpired classification + test for this
shape but left the obsolete TAURI-RUST-T BackendUserError test in place,
producing a contradiction: two tests assert different classifications for
identical input. On main, `is_embedding_backend_auth_failure` claims the
envelope first (line 392) and short-circuits before SessionExpired (line
335) can match, failing the newer test.

Three coordinated edits:

1. `is_embedding_backend_auth_failure` now skips the OpenHuman-backend
   envelope `"\"error\":\"invalid token\""` so BYO-key 401s (no envelope)
   still classify as BackendUserError but the 4K5 envelope falls through
   to SessionExpired. The function's narrative (third-party BYO-key
   rejection) is preserved.

2. `is_session_expired_message` now matches both the parenthesized
   (`Embedding API error (401`) and bare-status (`Embedding API error
   401`) wire shapes. Both are observed in production per the older
   TAURI-RUST-T test.

3. The obsolete `classifies_embedding_backend_auth_failure` test now
   asserts SessionExpired for both wire shapes — kept as a regression
   guard against `is_embedding_backend_auth_failure` re-claiming the
   envelope.

121 observability tests green.
sanil-23 added a commit to obchain/openhuman that referenced this pull request May 28, 2026
…ssionExpired

The TAURI-RUST-4K5 wire-shape (`Embedding API error (401 Unauthorized):
{"success":false,"error":"Invalid token"}`) is the OpenHuman backend's
session-expired envelope reaching the embeddings worker, not a backend
4xx bug. PR tinyhumansai#2786 added a SessionExpired classification + test for this
shape but left the obsolete TAURI-RUST-T BackendUserError test in place,
producing a contradiction: two tests assert different classifications for
identical input. On main, `is_embedding_backend_auth_failure` claims the
envelope first (line 392) and short-circuits before SessionExpired (line
335) can match, failing the newer test.

Three coordinated edits:

1. `is_embedding_backend_auth_failure` now skips the OpenHuman-backend
   envelope `"\"error\":\"invalid token\""` so BYO-key 401s (no envelope)
   still classify as BackendUserError but the 4K5 envelope falls through
   to SessionExpired. The function's narrative (third-party BYO-key
   rejection) is preserved.

2. `is_session_expired_message` now matches both the parenthesized
   (`Embedding API error (401`) and bare-status (`Embedding API error
   401`) wire shapes. Both are observed in production per the older
   TAURI-RUST-T test.

3. The obsolete `classifies_embedding_backend_auth_failure` test now
   asserts SessionExpired for both wire shapes — kept as a regression
   guard against `is_embedding_backend_auth_failure` re-claiming the
   envelope.

121 observability tests green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants