Skip to content

fix(openviking): prevent v0.3.3 HTTP 500s by normalizing /.overview.md and /.abstract.md pseudo-URIs before content reads - #5886

Closed
htsh wants to merge 3 commits into
NousResearch:mainfrom
htsh:fix/openviking-normalize-summary-uris-prevent-500
Closed

fix(openviking): prevent v0.3.3 HTTP 500s by normalizing /.overview.md and /.abstract.md pseudo-URIs before content reads#5886
htsh wants to merge 3 commits into
NousResearch:mainfrom
htsh:fix/openviking-normalize-summary-uris-prevent-500

Conversation

@htsh

@htsh htsh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Why this is necessary

I self host my own openviking setup and several hermes agents against it (local models + gpt 5.4) here and I kept running into this. This patch fixes it. Coded with hermes agent / gpt 5.3 codex.

OpenViking v0.3.3 content endpoints (/api/v1/content/overview, /api/v1/content/abstract) expect directory URIs.

The Hermes OpenViking plugin currently forwards pseudo-summary file URIs like:

  • viking://user/hermes/.overview.md
  • viking://resources/.abstract.md

That mismatch causes server-side HTTP 500 responses, so viking_read(level=overview|abstract) fails even though the backend is healthy and reachable.

Reproduction (before this patch)

  • viking_read(uri="viking://user/hermes/.overview.md", level="overview") -> 500
  • viking_read(uri="viking://resources/.abstract.md", level="abstract") -> 500

What this PR changes

  1. Normalize pseudo-summary URIs (/.overview.md, /.abstract.md, /.read.md, /.full.md) to their parent directory URI for abstract/overview reads.
  2. Keep full reads intact (no behavioral regression for level=full).
  3. Add response unwrapping for wrapped/unwrapped payloads.
  4. Harden browse parsing for fs list/tree response shape differences (list vs dict, isDir vs is_dir, missing name).

Verification

Validated against a live OpenViking v0.3.3 server:

  • overview read now resolves viking://user/hermes/.overview.md -> viking://user/hermes and succeeds
  • abstract read now resolves viking://resources/.abstract.md -> viking://resources and succeeds
  • full read of viking://user/hermes/memories/profile.md still succeeds
  • browse list still returns valid entries

Impact

This fixes a real integration breakage where normal user-facing viking_read calls fail with 500 due to URI shape mismatch, while preserving existing full-read behavior.

htsh added 2 commits April 7, 2026 13:26
OpenViking v0.3.3 expects directory URIs for abstract/overview reads.
Passing pseudo-files like /.overview.md and /.abstract.md to
/api/v1/content/overview|abstract triggers HTTP 500.

This change normalizes those pseudo-URIs to their parent directory for
abstract/overview requests, preserves full reads, and hardens parsing for
wrapped/unwrapped result payloads and fs list response shapes.

@ZaynJarvis ZaynJarvis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review: URI Normalization for OpenViking v0.3.3

Verdict: Approve — solid defensive fix with good test coverage

Checklist Pass

  • _normalize_summary_uri(): strips /.abstract.md, /.overview.md, /.read.md, /.full.md pseudo-file suffixes and returns the parent directory URI — correct for OV v0.3.3 which expects directory URIs for L0/L1 reads
  • Applied only for level in ("abstract", "overview")full reads still use the original URI (correct: full read targets the actual file)
  • _unwrap_result(): cleanly handles both {"result": ...} wrapped and raw unwrapped payloads
  • Browse response hardening: handles {"entries": ...\}/{"items": ...\}/{"children": ...\} dict shapes AND bare list — covers both v0.3.2 (bare list) and v0.3.3 (wrapped object) API shapes
  • Browse is_dir detection: checks isDir, is_dir, type == "dir" — handles camelCase and snake_case server variants
  • Tests: 101 lines, covers normalization edge cases, read with resolved_uri tracking, browse with dict-wrapped entries
  • resolved_uri field added to _tool_read response — useful for debugging URI resolution

Minor Suggestion (not blocking)

_normalize_summary_uri and _unwrap_result are both @staticmethod — they could be module-level functions, but keeping them as static methods on the class is fine for discoverability.

Merge after #9167 since both touch _tool_read/_tool_browse.

OpenViking returns 500 for /content/abstract and /content/overview when URI points to mem_*.md files.
Add resilient fallback to /content/read for non-pseudo summary file URIs while preserving pseudo summary normalization.
Also add regression tests for fallback behavior.
@htsh

htsh commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

Update from today's debugging (OpenViking v0.3.8):

Why this follow-up was necessary
- PR #5886 remains necessary (pseudo-summary URI normalization + response-shape handling), but it was not sufficient for current server behavior.
- On v0.3.8, `/api/v1/content/overview` and `/api/v1/content/abstract` return HTTP 500 when called with normal file URIs (e.g. `viking://.../mem_*.md`), while `/api/v1/content/read` succeeds for the same URI.

Evidence
- Reproduced via both Hermes `viking_read` and direct curl against `127.0.0.1:1933`.
- OpenViking container logs show:
  `ValueError: <uri> is not a directory`
  from the overview path, which explains the 500 on file URIs.

What this PR update adds
- Keeps the #5886 normalization behavior for pseudo-summary URIs (`/.overview.md`, `/.abstract.md`).
- Adds a resilience fallback for normal file URIs:
  - if `level=overview|abstract` hits a summary-endpoint error,
  - fallback to `/api/v1/content/read` for that URI,
  - include `fallback: "content/read"` in the tool payload.
- Adds regression tests for:
  - fallback behavior on summary endpoint failure for file URIs,
  - preserving strict behavior for pseudo-summary URIs.

Pushed commit in this PR branch:
- `9721bc5f91c8a531405984b38d8ed02ec6474856`

@htsh

htsh commented Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

@ZaynJarvis thanks again — I pushed a follow-up commit after testing against OpenViking v0.3.8. The original normalization fix still stands, but I found overview/abstract can also 500 on normal file URIs, so I added a fallback to content/read plus regression tests. If you have a moment, I’d appreciate a quick re-review."

@htsh
htsh requested a review from ZaynJarvis April 29, 2026 03:12
@ZaynJarvis

Copy link
Copy Markdown
Contributor

lgtm, i would flag for merge with hermes agent team. Thx

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins labels Apr 29, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #12755 — same root cause: OpenViking plugin routes file/pseudo-summary URIs to directory-only endpoints. Existing fix PRs: #12757, #12937.

@htsh

htsh commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

i do not mind which goes in

teknium1 added a commit that referenced this pull request Apr 30, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
#12757 and #12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from #5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #17869#17869

Your 3 commits were cherry-picked onto current main with your authorship preserved (rebase merge, not squash):

  • 97a851b — fix(openviking): normalize summary pseudo-URIs to prevent v0.3.3 500s
  • bff8ab0 — test(openviking): add helper regression coverage
  • 10e43ed — fix(openviking): fallback summary reads to content/read for file URIs

On top of your work we added an fs/stat pre-check as a follow-up commit so file URIs skip the directory-only endpoints entirely rather than eating a failing round-trip — the same idea @pty819 (#12757) and @chennest (#12937) independently landed on. All three of you credited in the salvage PR body and in scripts/release.py AUTHOR_MAP. Thanks for the thorough fix and tests!

donald131 pushed a commit to donald131/hermes-agent that referenced this pull request May 2, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
nickdlkk pushed a commit to nickdlkk/hermes-agent that referenced this pull request May 11, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
jsboige pushed a commit to jsboige/hermes-agent that referenced this pull request May 14, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
dannyJ848 pushed a commit to dannyJ848/hermes-agent that referenced this pull request May 17, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
Seven74AI pushed a commit to Seven74AI/hermes-agent that referenced this pull request Jun 13, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…directory-only endpoints

Adds a deterministic pre-check on top of htsh's exception-based fallback:
before calling /content/abstract or /content/overview on a non-pseudo URI,
probe /api/v1/fs/stat. If the server says the URI is a file, route straight
to /content/read instead of eating a failing 500 round-trip.

This is the same idea pty819 and chennest independently landed in PRs
NousResearch#12757 and NousResearch#12937 — merged here on top of htsh's broader fix so we keep
pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding
the slow exception path on servers that return a raised 500 every time.

The exception fallback from NousResearch#5886 stays in place for environments where
fs/stat is unavailable or returns an unfamiliar shape.

Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release
notes attribute them correctly.
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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants