Skip to content

fix: Vector namespaces must not contain slashes (Fixes BATTLE-MAGE-4) - #142

Merged
vlad-ko merged 2 commits into
mainfrom
fix/vector-namespace-slash
Jul 9, 2026
Merged

fix: Vector namespaces must not contain slashes (Fixes BATTLE-MAGE-4)#142
vlad-ko merged 2 commits into
mainfrom
fix/vector-namespace-slash

Conversation

@vlad-ko

@vlad-ko vlad-ko commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

Production bug caught by Sentry on the first live code-index cron tick (BATTLE-MAGE-4): every Upstash Vector operation was 404ing because our namespaces embed {owner}/{repo} and the SDK inserts the namespace into the REST path verbatim — POST /upsert-data/wealthbot-io/webo:src routes as endpoint /upsert-data/wealthbot-io + stray segment → Endpoint not found.

Blast radius: all three semantic arms — KB entry embedding, doc-chunk embedding, and the new code index — have been silently degrading to lexical-only in production since #134 deployed (each path is non-throwing by design, which is why only the cron tick surfaced it via Sentry). The provisioning-time round-trip verification passed because its scratch namespace had no slash.

Reproduced against the live index before fixing: slash namespace → the exact 404; underscore → works.

Fix

  • Shared namespacePrefix() = {owner}_{repo}; all three builders use it.
  • Regression test: no namespace builder can ever emit a /.
  • No migration needed: nothing was ever successfully written under the slashed namespaces — the fixed ones populate fresh on the next cron ticks / KB saves / index rebuild.

TDD: namespace pins flipped + regression test confirmed RED against the old builders, then the fix. Full suite 943 passing, typecheck clean.

Fixes BATTLE-MAGE-4 (Sentry)

🤖 Generated with Claude Code

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
battle-mage Ready Ready Preview, Comment Jul 9, 2026 2:43pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@vlad-ko, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d2ae8796-e17b-4958-b594-70bc8330a40c

📥 Commits

Reviewing files that changed from the base of the PR and between 6d18d9f and 0077a8e.

📒 Files selected for processing (6)
  • src/lib/code-index.test.ts
  • src/lib/knowledge.test.ts
  • src/lib/repo-index.test.ts
  • src/lib/vector.test.ts
  • src/lib/vector.ts
  • src/tools/search-repo.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/vector-namespace-slash

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix Upstash Vector namespaces to be slash-free via shared {owner}_{repo} prefix

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Replace {owner}/{repo} vector namespace prefixes with {owner}_{repo} to prevent Upstash REST
 404s.
• Centralize namespace prefix generation in src/lib/vector.ts for KB, docs, and src indexes.
• Add/adjust tests to pin namespaces and ensure no namespace builder can emit /.
Diagram

graph TD
  knowledge["knowledge.ts (KB embed)"] --> vector["vector.ts (namespacePrefix)"] --> upstash{{"Upstash Vector REST"}}
  repoIndex["repo-index.ts (docs embed)"] --> vector --> upstash
  codeIndex["code-index.ts (src index)"] --> vector --> upstash
  searchRepo["search-repo.ts (hybrid search)"] --> vector --> upstash
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. URL-encode `{owner}/{repo}` before passing to the SDK
  • ➕ Preserves the conceptual owner/repo hierarchy without changing naming semantics
  • ➕ Avoids delimiter-collision concerns across different repos/environments
  • ➖ Depends on how the Upstash SDK/server interpret encoded namespaces (could store literally-encoded strings)
  • ➖ More subtle to reason about and test than a simple delimiter change
2. Collision-safe prefix encoding (length-prefix or base64url)
  • ➕ Provably avoids collisions even when owners/repos contain underscores
  • ➕ Future-proofs if a single Upstash index is ever shared across multiple installations
  • ➖ Less readable namespaces for debugging/ops
  • ➖ Requires a conscious migration strategy if any data had been written

Recommendation: The PR’s approach (shared {owner}_{repo} prefix) is the most pragmatic fix for the immediate production outage: it is simple, readable, and fully covered by regression tests. If this system ever shares one Upstash index across multiple repos/installations, consider moving to a collision-safe encoding, but that seems unnecessary given the current “single-target bot” assumptions noted in code comments.

Files changed (6) +77 / -56

Bug fix (1) +16 / -3
vector.tsIntroduce shared slash-free namespacePrefix for all vector namespaces +16/-3

Introduce shared slash-free namespacePrefix for all vector namespaces

• Adds a 'namespacePrefix()' helper that joins 'GITHUB_OWNER' and 'GITHUB_REPO' with '_' instead of '/' to avoid Upstash REST path splitting. Updates 'kbNamespace', 'docsNamespace', and 'srcNamespace' to use the shared helper and documents the production failure mode (BATTLE-MAGE-4).

src/lib/vector.ts

Tests (5) +61 / -53
vector.test.tsUpdate namespace helper expectations and add no-slash regression test +29/-21

Update namespace helper expectations and add no-slash regression test

• Updates unit tests to expect underscore-separated namespaces for KB/docs/src. Adds a regression assertion that no namespace builder can ever emit a '/', pinning the BATTLE-MAGE-4 failure mode.

src/lib/vector.test.ts

code-index.test.tsAdjust code-index tests to use the new src/docs/kb namespaces +6/-6

Adjust code-index tests to use the new src/docs/kb namespaces

• Updates mocked namespace builders and expectations for 'vectorUpsert'/'vectorDelete' calls to use 'acme_backend:*' rather than 'acme/backend:*'. Ensures incremental code-index behavior remains the same while validating the corrected namespace format.

src/lib/code-index.test.ts

knowledge.test.tsUpdate KB embedding tests to expect underscore namespace +5/-5

Update KB embedding tests to expect underscore namespace

• Updates 'kbNamespace()' mock return value and all vector upsert/delete/query expectations to use 'acme_backend:kb', matching the new namespace prefix logic.

src/lib/knowledge.test.ts

repo-index.test.tsUpdate docs index tests for underscore-prefixed docs namespace pointers +11/-11

Update docs index tests for underscore-prefixed docs namespace pointers

• Adjusts docs namespace mocks and KV pointer expectations ('index:vector_docs_ns') to use 'acme_backend:docs:<sha>'. Keeps the pointer-swap and old-namespace cleanup ordering checks intact.

src/lib/repo-index.test.ts

search-repo.test.tsUpdate hybrid search tests to query underscore-prefixed namespaces +10/-10

Update hybrid search tests to query underscore-prefixed namespaces

• Updates src namespace mocks and docs namespace pointer values so the semantic arms use 'acme_backend:*'. Ensures the search tool still queries the stable src namespace and the docs pointer namespace with the expected limits.

src/tools/search-repo.test.ts

Comment thread src/lib/vector.ts
vlad-ko added a commit that referenced this pull request Jul 9, 2026
Per PR #142 review: Upstash creds without GITHUB_OWNER/GITHUB_REPO
would derive a shared undefined_undefined:* namespace and silently
contaminate retrieval. Missing identity now degrades through the
existing vector_unavailable path like missing creds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vlad-ko and others added 2 commits July 9, 2026 10:42
The Upstash Vector REST client inserts the namespace into the URL path
verbatim, so the {owner}/{repo} prefix in kbNamespace/docsNamespace/
srcNamespace split the route and 404'd every vector operation in
production (first surfaced by the code-index tick's upsert; KB and doc
embedding were silently degrading the same way). Reproduced against the
live index: slash → 'Endpoint not found', underscore → ok.

Prefix is now {owner}_{repo} via a shared helper; a regression test
pins that no namespace builder can ever emit a slash. Nothing was
successfully written under the slashed namespaces, so there is no
migration — the fixed namespaces populate fresh on the next ticks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per PR #142 review: Upstash creds without GITHUB_OWNER/GITHUB_REPO
would derive a shared undefined_undefined:* namespace and silently
contaminate retrieval. Missing identity now degrades through the
existing vector_unavailable path like missing creds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vlad-ko
vlad-ko force-pushed the fix/vector-namespace-slash branch from 97cb35e to 0077a8e Compare July 9, 2026 14:42
@vlad-ko
vlad-ko merged commit 1ff4751 into main Jul 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant