Skip to content

fix(observability): demote OpenHuman backend unknown-model 400 (TAURI-RUST-2Z1)#2464

Open
CodeGhost21 wants to merge 2 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/tauri-rust-2z1-unknown-model-polarity
Open

fix(observability): demote OpenHuman backend unknown-model 400 (TAURI-RUST-2Z1)#2464
CodeGhost21 wants to merge 2 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/tauri-rust-2z1-unknown-model-polarity

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 21, 2026

Summary

The OpenHuman hosted backend now emits the OpenAI-compatible Model 'X' is not available. Use GET /openai/v1/models … wire body for user-configured unknown model ids. The HTTP-layer wrapper is_provider_config_rejection_http in src/openhuman/inference/provider/ops.rs was polarity-gated on provider != openhuman_backend::PROVIDER_LABEL for all config-rejection phrases — built on the older assumption that only third-party custom_openai upstreams would speak this dialect. So the per-attempt event from a user-typed unknown model id reached Sentry as a real error (TAURI-RUST-2Z1) even though the underlying condition is pure user-state.

This PR drops the polarity guard for that one specific shape via a narrow new helper is_openai_compatible_unknown_model_message, anchored on the stable /openai/v1/models remediation-hint substring. Every other config-rejection phrase (DeepSeek supported api model names are, Moonshot invalid temperature: only 1 is allowed, litellm envelopes, OpenRouter requires more credits) stays polarity-gated so a regression where our own backend started emitting one of those would still reach Sentry.

The aggregate sibling TAURI-RUST-2Z2 is already auto-demoted by the message-only classifier in core::observability::expected_error_kind (via #2239's /openai/v1/models phrase). This PR addresses the missing per-attempt half.

What changed

  • src/openhuman/inference/provider/config_rejection.rs
    • Added is_openai_compatible_unknown_model_message(body) — strict subset of the broader phrase matcher, pinned to /openai/v1/models.
    • Updated module-level polarity contract docs to call out the new exception.
  • src/openhuman/inference/provider/ops.rs
    • is_provider_config_rejection_http now bypasses the openhuman_backend polarity guard only when is_openai_compatible_unknown_model_message matches; all other config-rejection phrases retain the guard.
    • Existing doc-comment updated to reflect the exception.
  • src/openhuman/inference/provider/mod.rs
    • Re-export is_openai_compatible_unknown_model_message for cross-module access.

Test plan

  • cargo test --lib openhuman::inference::provider::config_rejection — 6 passed, including two new tests: unknown_model_helper_matches_openai_compatible_bodies (pins the exact TAURI-RUST-2Z1 wire body) and unknown_model_helper_rejects_other_config_rejection_phrases (guards the narrow-scope invariant).
  • cargo test --lib openhuman::inference::provider::ops::tests::provider_config_rejection_suppression — 7 passed, including a new test openhuman_backend_openai_compatible_unknown_model_is_suppressed plus an additional assertion in the existing openhuman_backend_same_body_is_not_suppressed test confirming TIER_LEAK_BODY and TEMP_BODY both still bypass demotion for the backend.
  • cargo test --lib openhuman::inference::provider — 272 passed, 0 failed.
  • cargo test --lib core::observability — 81 passed, 0 failed (no regression in the message-only classifier path).
  • cargo fmt clean, cargo check --lib clean (only pre-existing unrelated warnings).

Polarity rationale

The narrow helper is the polarity-safe minimum: only the OpenAI-compatible "unknown model" body shape is now treated as user-state regardless of provider. The hosted backend has deliberately adopted that wire shape to mirror the OpenAI /v1/models contract, and the same body carries the same user-state semantics whether the upstream is custom_openai, DeepSeek, OpenRouter, or our own backend. Other phrases that the backend does not emit stay actionable.

If the backend ever starts emitting one of the polarity-gated phrases in error, the existing openhuman_backend_same_body_is_not_suppressed regression test will keep firing the Sentry event so we'd see it.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of "unknown model" errors from OpenAI-compatible services to ensure consistent behavior across all provider types, including the hosted backend.
  • Tests

    • Added test coverage for the new error handling logic, including validation across different model variants.

Review Change Stack

…-RUST-2Z1)

The OpenHuman hosted backend now emits the OpenAI-compatible "Model 'X' is
not available. Use GET /openai/v1/models …" wire body for user-configured
unknown model ids — a body shape the polarity guard in
`is_provider_config_rejection_http` had previously assumed only third-party
`custom_openai` upstreams would speak. Result: the per-attempt event
reached Sentry as a real error (TAURI-RUST-2Z1) even though the underlying
condition is pure user-state (the user typed an unknown model id and
configured `model_fallbacks` with `custom:`-prefixed variants that the
backend also rejected).

Drop the polarity guard for that one body shape via a new narrow helper
`is_openai_compatible_unknown_model_message` anchored on the
`/openai/v1/models` remediation hint. Other config-rejection phrases
(DeepSeek `supported api model names are`, Moonshot `invalid temperature`,
litellm envelopes, OpenRouter `requires more credits`) stay polarity-gated
so a regression where our own backend started emitting them would still
reach Sentry.

The aggregate sibling TAURI-RUST-2Z2 is already auto-demoted by the
message-only classifier in `core::observability::expected_error_kind`
(via tinyhumansai#2239's `/openai/v1/models` phrase).
@CodeGhost21 CodeGhost21 requested a review from a team May 21, 2026 19:55
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

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: 5f10aa0a-b908-4e46-a70b-62f289612c9c

📥 Commits

Reviewing files that changed from the base of the PR and between c9ab4b9 and 8ac8a1f.

📒 Files selected for processing (3)
  • src/openhuman/inference/provider/config_rejection.rs
  • src/openhuman/inference/provider/mod.rs
  • src/openhuman/inference/provider/ops.rs

📝 Walkthrough

Walkthrough

This PR adds a new classifier for OpenAI-compatible "unknown model" error messages and integrates it into the HTTP rejection suppression logic. The classifier detects the specific wire shape via the /openai/v1/models remediation hint, and suppresses those payloads as user-state regardless of provider, including the OpenHuman backend. All other config-rejection phrases retain the existing provider-polarity guard.

Changes

Unknown Model Suppression

Layer / File(s) Summary
Unknown model classifier definition and tests
src/openhuman/inference/provider/config_rejection.rs, src/openhuman/inference/provider/mod.rs
New public predicate is_openai_compatible_unknown_model_message() detects the /openai/v1/models remediation hint substring in error bodies; module documentation clarifies this as a polarity exception; test coverage verifies the classifier matches hosted-backend/third-party unknown-model bodies and does not match other config-rejection phrases; function is re-exported via the provider module.
HTTP rejection suppression integration
src/openhuman/inference/provider/ops.rs
is_provider_config_rejection_http() now suppresses OpenAI-compatible unknown-model messages regardless of provider, including OpenHuman backend, while preserving the backend-vs-non-backend polarity guard for all other config-rejection phrases; test suite updated to verify backend non-suppression of tier-leak/temperature bodies and backend suppression of unknown-model variants.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • tinyhumansai/openhuman#2346: Uses is_provider_config_rejection_http in streaming paths for logging/suppression, so the behavior change in this PR directly impacts how those streaming config-rejection errors are handled.
  • tinyhumansai/openhuman#2239: Extends the provider-config-rejection pipeline with ProviderConfigRejection wiring and suppression, overlapping with the main PR's new predicate and modified is_provider_config_rejection_http behavior.
  • tinyhumansai/openhuman#2309: Touches the same config_rejection.rs classification logic; the main PR adds an OpenAI-compatible unknown-model exception while the retrieved PR expands the generic phrase matcher, both refining what payloads are treated as deterministic user-state.

Suggested labels

working, bug

Suggested reviewers

  • senamakel
  • graycyrus

Poem

🐰 A model's name was deemed unknown,
So /openai/v1/models made its moan.
Now OpenHuman heeds the call,
Classifies the error—and suppresses all!
User-state it stays, both far and wide,
No more polarity guards to hide. 🎯

🚥 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 pull request title clearly and specifically describes the main change: demoting OpenHuman backend unknown-model 400 errors to suppress user-state observability noise.
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.

✏️ 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 21, 2026
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.

1 participant