tinyhumansai/openhuman · error

OpenHuman uses the session JWT — keys are not configurable h

Error message

OpenHuman uses the session JWT — keys are not configurable here.

What it means

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.

Source

Thrown at app/src/services/api/aiSettingsApi.ts:453

      !!m &&
      m.vision === e.vision &&
      m.cost_per_1m_output === e.cost_per_1m_output &&
      (m.cost_per_1m_input ?? 0) === (e.cost_per_1m_input ?? 0) &&
      (m.cost_per_1m_cached_input ?? 0) === (e.cost_per_1m_cached_input ?? 0) &&
      (m.context_window ?? 0) === (e.context_window ?? 0)
    );
  });
}

// ─── API key management (per cloud provider slug) ──────────────────────────

/**
 * Store an API key for a cloud provider (encrypted at rest). Keyed by slug
 * using the new `provider:<slug>` format.
 */
export async function setCloudProviderKey(slug: string, apiKey: string): Promise<void> {
  if (slug === 'openhuman') {
    throw new Error('OpenHuman uses the session JWT — keys are not configurable here.');
  }
  // Store under both new-style key `provider:<slug>` and legacy bare `<slug>`
  // so old code paths that look up by bare slug continue to work.
  await authStoreProviderCredentials({
    provider: authKeyForSlug(slug),
    profile: 'default',
    token: apiKey,
    setActive: true,
  });
}

/**
 * Outcome of a post-save connection check (#5146 §2.4).
 *
 * `ok: false` means the credential was stored but the provider could not
 * actually serve an inference call — the "connected but unusable" state where
 * the UI previously showed a healthy provider that failed on first real use.
 */

View on GitHub (pinned to a221052e0d)

Solutions

  1. Filter the OpenHuman entry out of BYOK key-management UI, or render it as 'managed via your account login' with the input disabled
  2. If a settings import/migration script loops over slugs, skip 'openhuman' explicitly
  3. For OpenHuman auth problems, fix the login/session (re-auth), not the key store

Example fix

// before
providers.map(p => <KeyForm slug={p.slug} onSave={(k) => setCloudProviderKey(p.slug, k)} />);

// after
providers.map(p =>
  p.slug === 'openhuman'
    ? <ManagedAuthNote key={p.slug} />
    : <KeyForm key={p.slug} slug={p.slug} onSave={(k) => setCloudProviderKey(p.slug, k)} />
);
Defensive patterns

Strategy: type-guard

Validate before calling

const isByokSlug = (slug: string): boolean => slug !== 'openhuman';
if (isByokSlug(slug)) await setCloudProviderKey(slug, apiKey);
else showManagedAuthNotice();

Type guard

const isByokSlug = (slug: string): slug is Exclude<string, 'openhuman'> => slug !== 'openhuman';

Try / catch

try { await setCloudProviderKey(slug, apiKey); }
catch (e) { if (String(e.message).includes('session JWT')) showNotice('OpenHuman auth is handled by your login.'); else throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/edc40f4d180127b6. Report an issue: GitHub.