Skip to content

fix: always send tenant headers in OpenViking _headers() when account/user are set#21775

Closed
happy5318 wants to merge 1 commit into
NousResearch:mainfrom
happy5318:fix/openviking-root-key-tenant-headers
Closed

fix: always send tenant headers in OpenViking _headers() when account/user are set#21775
happy5318 wants to merge 1 commit into
NousResearch:mainfrom
happy5318:fix/openviking-root-key-tenant-headers

Conversation

@happy5318

Copy link
Copy Markdown
Contributor

Problem

The _headers() method in plugins/memory/openviking/__init__.py skips X-OpenViking-Account and X-OpenViking-User headers when their values equal "default":

if self._account and self._account != "default":
    h["X-OpenViking-Account"] = self._account
if self._user and self._user != "default":
    h["X-OpenViking-User"] = self._user

This causes INVALID_ARGUMENT errors from OpenViking 0.3.x servers when using the ROOT API key, because ROOT-key requests to tenant-scoped APIs require these headers explicitly — even when the account is the literal string "default".

Error message:

ROOT requests to tenant-scoped APIs must include X-OpenViking-Account and X-OpenViking-User headers. Use a user key for regular data access.

Fix

Remove the != "default" guard so headers are always sent when account/user are non-empty:

if self._account:
    h["X-OpenViking-Account"] = self._account
if self._user:
    h["X-OpenViking-User"] = self._user

User-level keys derive tenancy from the key itself and can omit these headers, but ROOT keys cannot.

Testing

  • Verified on OpenViking 0.3.14 with ROOT API key + account="default" + user="hermes"
  • Session commit, search, and all tenant-scoped APIs work correctly after the fix
  • No regressions with user-level keys (tested both with and without explicit headers)

…/user are set

The _headers() method previously skipped X-OpenViking-Account and
X-OpenViking-User headers when their values equaled "default".
This caused INVALID_ARGUMENT errors from OpenViking 0.3.x servers
when using the ROOT API key, because ROOT-key requests to
tenant-scoped APIs require these headers explicitly — even when
the account is the literal string "default".

User-level keys derive tenancy from the key itself and can omit
these headers, but ROOT keys cannot. Remove the != "default"
guard so headers are always sent when account/user are non-empty.
@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers P3 Low — cosmetic, nice to have labels May 8, 2026
@ZaynJarvis

ZaynJarvis commented May 9, 2026

Copy link
Copy Markdown
Contributor

agree, will fix

@ZaynJarvis

Copy link
Copy Markdown
Contributor

this is a bug.

While this happens to root api key access. A simple workaround is to use default user apikey. Then these two are not required.

@kshitijk4poor kshitijk4poor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

PR Review — #21775: fix: always send tenant headers in OpenViking _headers() when account/user are set

Verdict: Request Changes
Tests: 18 passed, 2 failed (0 pre-existing — both new regressions)
Changes: 1 file, +8/-7 lines

Critical

  • tests/plugins/memory/test_openviking_provider.py:317–332test_viking_client_headers_omit_tenant_when_legacy_default asserts that X-OpenViking-Account and X-OpenViking-User are NOT sent when account="default", user="default". The PR changes this behavior so these headers ARE now sent when account/user are truthy (which "default" is). This test fails and must be updated to assert the headers are present instead.

  • tests/plugins/memory/test_openviking_provider.py:335–347test_viking_client_headers_omit_tenant_when_empty passes account="" and user="", but the constructor translates empty strings to "default" via "" or os.environ.get("OPENVIKING_ACCOUNT", "default"). So self._account is actually "default", not empty — and the PR now sends the header. This test also fails and must be updated.

Warnings

  • tests/plugins/memory/test_openviking_provider.py:335 — The test name omit_tenant_when_empty is misleading. The constructor's or "default" fallback means passing "" results in self._account = "default", so the test was never testing the true-empty case. Consider splitting into: (a) a proper "truly empty" test (monkeypatch OPENVIKING_ACCOUNT="" so self._account = "", assert no headers), and (b) a "default via constructor fallback" test (account unset → defaults to "default" → headers ARE sent).

Looks Good

  • The core fix is correct: removing != "default" guard so ROOT API keys can always send tenant headers
  • The updated docstring in _headers() is accurate and explains the motivation clearly
  • Only touches the plugin file (plugins/memory/openviking/__init__.py) — no core hermes-agent files
  • The if self._account: / if self._user: guards still correctly prevent sending empty-string headers
  • Author is in AUTHOR_MAP ✓

kshitijk4poor added a commit that referenced this pull request May 9, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on #21775 by @happy5318
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Merged via #22414 with test updates — thanks @happy5318!

JZKK720 pushed a commit to JZKK720/hermes-agent that referenced this pull request May 11, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
rmulligan pushed a commit to rmulligan/hermes-agent that referenced this pull request May 11, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
JinyuID pushed a commit to JinyuID/hermes-agent that referenced this pull request May 11, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
jsboige pushed a commit to jsboige/hermes-agent that referenced this pull request May 14, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request May 25, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
…/user are set

OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors.

Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy.

Update tests to reflect the new behavior:
- test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present
- test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback

Based on NousResearch#21775 by @happy5318
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants