Skip to main content
← Back to list
01Issue
BugOpenExtensionsPublic
AssigneesNone

Relationships

#1735 knowledge-base retrieve persists query output into the state resource, with lifetime infinite and the query text in the instance name

Opened by esteban · 8/19/2026

Summary

@swamp/aws/bedrock/knowledge-base.retrieve (added in 2026.08.18.1, from feature request #1571 — thank you for shipping it) calls the Bedrock data plane correctly, but persists its result into the model's state resource. state is the knowledge base's own configuration state: declared lifetime: "infinite", and its schema requires KnowledgeBaseId while describing KnowledgeBaseConfiguration, StorageConfiguration, RoleArn, Status. A retrieval result does not fit that shape, is retained forever, and lands under an instance name built from every argument value — including the natural-language query.

All line references below are from the pulled source of 2026.08.19.1, re-verified today.

The code

models/knowledge_base.ts:1253-1269:

const result = await retrieve(mergedArgs, credentials);
const argKeys = Object.keys(args).filter((k) => args[k] !== undefined);
const suffix = argKeys.length > 0
  ? "-" + argKeys.map((k) => String(args[k])).join("-")
  : "";
const instanceName = ("retrieve" + suffix).replace(/[\/\\]/g, "_")
  .replace(/\.\./g, "_").replace(/\0/g, "");
const handle = await context.writeResource("state", instanceName, result);

The target resource, models/knowledge_base.ts:989-995:

resources: {
  state: {
    description: "Bedrock KnowledgeBase resource state",
    schema: StateSchema,
    lifetime: "infinite",
    garbageCollection: 10,
  },
},

Three problems, in order of severity

# Problem Why it matters
1 Writes into state StateSchema (:764-795) has KnowledgeBaseId: z.string() required, plus optional KnowledgeBaseConfiguration, StorageConfiguration, RoleArn, Status, CreatedAt... The retrieve payload is { results, resultCount, nextToken? } (:696-742) and carries no KnowledgeBaseId at all, so it cannot satisfy the schema. It also occupies the slot that genuine resource state belongs in — a retrieve call and a sync call now write the same resource with unrelated shapes
2 lifetime: "infinite" Correct for configuration state, wrong for query output. Retrieval results never expire
3 Instance name embeds every argument value retrieve-<query text>-<kbId>-<numberOfResults>-..., path-sanitized. The full natural-language query becomes part of a data instance name: unbounded cardinality, unreadable in data list, and a brand-new instance for every distinct question asked

Note that 2 and 3 compound. garbageCollection: 10 caps versions per instance name, so it would bound things if retrievals reused one name — but because every distinct query produces a new name, the cap never engages. The result is an unbounded set of instances, each retained forever.

Honest scope note: problem 1 is read from the two schemas rather than from a failed run — we renamed our own method to coexist (see below) and have been using that, so I have not observed whether the mismatch throws at validation or is stored unvalidated. Either way the resource choice looks unintended.

Suggested fix

Declare a dedicated resource for retrieval rather than reusing state:

  • a retrieval resource whose schema describes chunks — text, score, metadata, location, sourceUri;
  • a short lifetime such as 7d with garbageCollection set, since query output is derived data;
  • an instance name from something stable and low-cardinality — the knowledge-base ID is the natural key — instead of the query text.

A working reference implementation

This repo has been doing exactly that since before the first-party method existed (it is what prompted #1571): dedicated retrieval resource, lifetime: "7d", garbageCollection: 10, instance keyed by knowledgeBaseId. Live-verified against Bedrock: 3 chunks with real relevance scores in 1875ms, persisting to exactly one instance named after the KB ID at v13 — no per-query instance sprawl. Happy to offer it as a reference or a patch if that is useful.

Why we still carry ours

Our extension is named retrieve_chunks, not retrieve, because a method-name collision between a base type and an extending extension silently drops the whole extension file — filed separately as swamp Lab #1734. Once the persistence here is fixed, our extension becomes redundant and we delete it outright; that is the outcome we are after.

Environment

  • @swamp/aws/bedrock 2026.08.19.1 (identical model source to 2026.08.18.1 — that release changed only the version string in manifest.yaml)
  • swamp 20260809.004828.0-sha.b61c9de2, Deno 2.8.3, Linux x86_64
  • Related: #1571 (the request that added retrieve), #1734 (silent collision, why we cannot simply drop ours)

Upstream repository: https://github.com/swamp-club/swamp-extensions

Environment

  • Extension: @swamp/aws/bedrock@2026.08.19.1
  • swamp: 20260819.011806.0-sha.a9c7ee9a
  • OS: linux (x86_64)
  • Deno: 2.8.3
  • Shell: /bin/zsh
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/19/2026, 9:06:09 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.