OHMOHM Studio

Troubleshooting

Common errors and how to fix them — HTTP status codes, SDK error classes, key issues, language pitfalls, and rate limits.

View as Markdown

This page is the single source of truth for "my call failed, what now?" Bookmark it.

Quick triage

SymptomMost likely causeFix
401 UnauthorizedWrong / missing / revoked API keyRe-mint the key in Studio Keys page
401 Unauthorized after working beforeOrg suspendedCheck with your admin; suspended orgs revoke all keys
403 ForbiddenLive key in mobile bundleUse ohms_test_* for dev, proxy live keys via your backend
404 Not Found on /extract/:slugAPI not published / wrong slugClick Publish in Studio; verify the slug in the URL
422 Unprocessable EntityRequired input missing or wrong typeRead error.fields[] for the exact JSON-Schema path
429 Too Many RequestsPer-key rate limit hitBack off using error.retryAfterSec
OHMValidationError thrownServer returned data that didn't match the SDK's expected shapeUsually a server bug — copy the requestId and contact support
Empty data objectThe transcript didn't mention anything in your schemaInspect result.transcript — the LLM is faithful, garbage-in = empty-out
Transcript is in a non-English scriptYou're calling the wrong endpointaudio.transcribe and audio.extract always return English — but extract (text-in) trusts whatever you send it

Error classes (all SDKs)

Every SDK call that fails throws a typed error. Pattern-match by class:

import {
  OHMError,                  // base class
  OHMAuthError,              // 401 / 403
  OHMValidationError,        // 422 — has `fields: string[]`
  OHMRateLimitError,         // 429 — has `retryAfterSec?: number`
  OHMServerError,            // 5xx
} from "@ohm_studio/sdk";

try {
  await ohm.audio.extract({ apiSlug, file });
} catch (e) {
  if (e instanceof OHMRateLimitError) {
    await sleep((e.retryAfterSec ?? 1) * 1000);
    return retry();
  }
  if (e instanceof OHMAuthError) {
    rotateKey();
    return;
  }
  if (e instanceof OHMValidationError) {
    console.warn("schema mismatch at", e.fields);
    return showFieldErrors(e.fields);
  }
  if (e instanceof OHMServerError) {
    log.error({ requestId: e.requestId, code: e.code }, "OHM server error");
    return showFriendlyError();
  }
  // Network / timeout / unknown
  throw e;
}

Every error has:

FieldTypeNotes
messagestringHuman-readable
codestringMachine-readable enum (e.g. "INVALID_API_KEY", "RATE_LIMITED")
statusnumberHTTP status
requestIdstring | undefinedQuote this in support tickets — we look it up directly

requestId is the single thing to copy when contacting support. With it we can pull your exact request from server logs in seconds; without it we're guessing.

"I copied the API key but get 401"

Three things to check, in order:

  1. Whitespace. Copy-paste sometimes adds a leading newline. console.log(apiKey.length) — should be a fixed length, no surrounding whitespace.
  2. Mode mismatch. ohms_test_* keys only hit test-mode endpoints; ohms_live_* only hit live. The SDK forwards whichever you give it.
  3. Wrong project. Each project has its own keys. If you minted the key under "Project A" but the API you're calling lives in "Project B", you'll 401.

If all three are clean, mint a new key — keys can't be "viewed again" after the first reveal, so a copy mistake is unrecoverable. The old key stays valid until you revoke it.

Live keys leaked into a public bundle?

Revoke the key from Studio immediately. The server marks it revokedAt; the next request from that key returns 401. No one can reuse it.

"My transcript is in Tamil/Hindi/Telugu — I expected English"

You're probably calling extract (text-only) with the raw STT output from another provider. OHM's audio.transcribe and audio.extract always return English (OHM's STT runs in translate mode), but the text-only extract endpoint trusts whatever you send it.

Two fixes:

  • Use audio.extract instead of running STT yourself. One call, audio in, English transcript + structured JSON out.
  • Translate before calling extract if you must use a custom STT pipeline. The clinical foundation prompt is English-first.

"Structured extraction failed after 3 attempts: No object generated"

This used to happen intermittently when the LLM provider wrapped its JSON response in markdown code fences. The server now applies the Vercel AI SDK's extractJsonMiddleware (an official SDK middleware documented for exactly this case), which strips fences before the JSON parser runs. If you saw this error before May 2026, it's gone in the current server build — no client change required.

"Extraction is empty / missing fields"

Three usual causes:

  1. The fact wasn't in the transcript. OHM's extraction is faithful — it extracts what was actually said, not what should have been said. Open the Studio Playground, paste the transcript, and watch which fields populate. If they're empty in Playground too, the LLM is correctly omitting them.
  2. The schema field doesn't match the doctor's wording. Add a helpText to the field describing how the speaker phrases it ("e.g. 'BP one fifty by ninety'"). The Foundation Block uses field labels + helpText to route facts.
  3. Foundation Block was disabled for this API. Check Studio → API → Settings. The opt-out is per-API; un-toggle to restore the clinical safety priors.

Rate limits

Per-key rate limits are configurable in Studio → Project → Keys. Default is 60 requests/minute per key. On 429, the SDK throws OHMRateLimitError with retryAfterSec — back off for at least that long.

For sustained higher throughput, mint multiple keys (one per worker) or contact support to raise the limit.

"The Studio Playground works but the SDK call fails"

Almost always means the API hasn't been published since your last edit. Studio Playground runs against the draft spec; the SDK calls the published snapshot. Click Publish in the API builder.

Less commonly:

  • The published key is from a different project than the one you're calling.
  • You renamed the API slug after publishing (the old slug is gone).

"ohms_live_ keys are blocked in my React Native app"

That's the SDK protecting you. Live keys in a mobile bundle are extractable by anyone who downloads the IPA / APK. Two production patterns:

  • Backend proxy (recommended). Your RN app calls your backend with a session token; your backend calls OHM with the live key. See RN Key Handling for the full pattern.
  • Test-mode keys for development. ohms_test_* keys are bundle-safe — they hit test endpoints with no PHI risk. Use them in sandbox builds and for local development.

If you really need to bundle a live key (e.g. an internal-only tablet kiosk), pass acknowledgeBundledKey: true to the constructor — but consider this a code smell.

Still stuck?

Email support@ohm.doctor with:

  • The requestId from the error (single most important thing)
  • The SDK package + version (@ohm_studio/sdk@x.y.z)
  • A minimal reproduction (cURL + redacted transcript is enough)

We respond within one business day for paid orgs, two for free.