{"record":{"id":"edc40f4d180127b6","repo":"tinyhumansai/openhuman","slug":"openhuman-uses-the-session-jwt-keys-are-not-conf","errorCode":null,"errorMessage":"OpenHuman uses the session JWT — keys are not configurable here.","messagePattern":"OpenHuman uses the session JWT — keys are not configurable here\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/services/api/aiSettingsApi.ts","lineNumber":453,"sourceCode":"      !!m &&\n      m.vision === e.vision &&\n      m.cost_per_1m_output === e.cost_per_1m_output &&\n      (m.cost_per_1m_input ?? 0) === (e.cost_per_1m_input ?? 0) &&\n      (m.cost_per_1m_cached_input ?? 0) === (e.cost_per_1m_cached_input ?? 0) &&\n      (m.context_window ?? 0) === (e.context_window ?? 0)\n    );\n  });\n}\n\n// ─── API key management (per cloud provider slug) ──────────────────────────\n\n/**\n * Store an API key for a cloud provider (encrypted at rest). Keyed by slug\n * using the new `provider:<slug>` format.\n */\nexport async function setCloudProviderKey(slug: string, apiKey: string): Promise<void> {\n  if (slug === 'openhuman') {\n    throw new Error('OpenHuman uses the session JWT — keys are not configurable here.');\n  }\n  // Store under both new-style key `provider:<slug>` and legacy bare `<slug>`\n  // so old code paths that look up by bare slug continue to work.\n  await authStoreProviderCredentials({\n    provider: authKeyForSlug(slug),\n    profile: 'default',\n    token: apiKey,\n    setActive: true,\n  });\n}\n\n/**\n * Outcome of a post-save connection check (#5146 §2.4).\n *\n * `ok: false` means the credential was stored but the provider could not\n * actually serve an inference call — the \"connected but unusable\" state where\n * the UI previously showed a healthy provider that failed on first real use.\n */","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/api/aiSettingsApi.ts#L435-L471","documentation":"aiSettingsApi.setCloudProviderKey refuses the slug 'openhuman': OpenHuman's own inference path authenticates with the session JWT obtained at login, not with a user-entered API key, so there is nothing to store. The check happens before any credential write.","triggerScenarios":"Calling setCloudProviderKey('openhuman', key) — e.g. a generic 'add API key' form that iterates provider slugs and includes the built-in OpenHuman entry, or a user pasting an OpenAI key while the OpenHuman row is selected.","commonSituations":"A provider settings list that mixes hosted OpenHuman with BYOK cloud providers (openai, anthropic, ...) and reuses one save handler; confusion between the OpenHuman account (JWT) and third-party provider keys.","solutions":["Filter the OpenHuman entry out of BYOK key-management UI, or render it as 'managed via your account login' with the input disabled","If a settings import/migration script loops over slugs, skip 'openhuman' explicitly","For OpenHuman auth problems, fix the login/session (re-auth), not the key store"],"exampleFix":"// before\nproviders.map(p => <KeyForm slug={p.slug} onSave={(k) => setCloudProviderKey(p.slug, k)} />);\n\n// after\nproviders.map(p =>\n  p.slug === 'openhuman'\n    ? <ManagedAuthNote key={p.slug} />\n    : <KeyForm key={p.slug} slug={p.slug} onSave={(k) => setCloudProviderKey(p.slug, k)} />\n);","handlingStrategy":"type-guard","validationCode":"const isByokSlug = (slug: string): boolean => slug !== 'openhuman';\nif (isByokSlug(slug)) await setCloudProviderKey(slug, apiKey);\nelse showManagedAuthNotice();","typeGuard":"const isByokSlug = (slug: string): slug is Exclude<string, 'openhuman'> => slug !== 'openhuman';","tryCatchPattern":"try { await setCloudProviderKey(slug, apiKey); }\ncatch (e) { if (String(e.message).includes('session JWT')) showNotice('OpenHuman auth is handled by your login.'); else throw e; }","preventionTips":["Keep managed providers and BYOK providers in separate UI lists","Render the OpenHuman row as login status, never as a key form","Skip 'openhuman' in any slug-looping migration/import script"],"tags":["validation","ai-settings","authentication","byok"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}