fix: guard QMD session stem fallback (#86482)

Summary:
- This PR changes `resolveTranscriptStemToSessionKeys` to skip empty or missing `sessionId` values during QMD slug fallback, adds regression coverage, and adds a changelog entry.
- PR surface: Source +1, Tests +17, Docs +1. Total +19 across 3 files.
- Reproducibility: yes. from source inspection: current main reaches `normalizeQmdSessionStem(entry.sessionId) ... ad-only review, but the source PR includes a direct after-fix resolver probe for the same mixed-store case.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: guard QMD session stem fallback
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8632…

Validation:
- ClawSweeper review passed for head 81478b0ee6.
- Required merge gates passed before the squash merge.

Prepared head SHA: 81478b0ee6
Review: https://github.com/openclaw/openclaw/pull/86482#issuecomment-4534348706

Co-authored-by: abnershang <abner.shang@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Abner Shang <75654486+abnershang@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
This commit is contained in:
clawsweeper[bot]
2026-05-25 14:35:43 +00:00
committed by GitHub
parent 489e415339
commit 2e3b59bc58
3 changed files with 20 additions and 1 deletions

View File

@@ -23,6 +23,7 @@ Docs: https://docs.openclaw.ai
- Media understanding: convert HEIC and HEIF images to JPEG before image description providers run so iPhone photos work in direct and configured image-description flows. (#86037)
- Agents: release embedded-attempt session locks from outer teardown so post-prompt exceptions cannot wedge later requests behind `SessionWriteLockTimeoutError`. Fixes #86014. Thanks @openperf.
- Discord/OpenAI voice: rotate Realtime sessions at provider max duration without logging the expected session-expiry event as an error.
- Sessions: skip metadata-only entries during QMD-slugified session lookup so one incomplete row does not block transcript hit resolution. (#86327) Thanks @abnershang.
- Agents/media: derive bundled plugin local-media trust from plugin tool metadata instead of importing the full plugin registry on subscription paths. (#84409) Thanks @samzong.
- Image tool: keep config-backed custom-provider API keys usable for auto-discovered vision models, including deferred image-tool execution without env keys or auth profiles. (#85733)
- Memory/local embeddings: run local GGUF embeddings in an isolated worker sidecar and degrade to configured fallback or keyword search on worker failure so native embedding crashes do not take down the Gateway. (#85348) Thanks @osolmaz.

View File

@@ -217,6 +217,23 @@ describe("resolveTranscriptStemToSessionKeys", () => {
).toEqual(["agent:main:s1"]);
});
it("ignores store entries without session ids during QMD-slugified fallback", () => {
const store: Record<string, SessionEntry> = {
"agent:main:non-session": {
updatedAt: 1,
} as SessionEntry,
"agent:main:s1": baseEntry({ sessionId: "foo_bar.v1" }),
};
expect(
resolveTranscriptStemToSessionKeys({
store,
stem: "foo-bar-v1",
allowQmdSlugFallback: true,
}),
).toEqual(["agent:main:s1"]);
});
it("does not use QMD-slugified fallback unless requested", () => {
const store: Record<string, SessionEntry> = {
"agent:main:s1": baseEntry({ sessionId: "foo_bar.v1" }),

View File

@@ -151,7 +151,8 @@ export function resolveTranscriptStemToSessionKeys(params: {
continue;
}
}
if (normalizeQmdSessionStem(entry.sessionId) === normalizedStem) {
const entrySessionId = normalizeOptionalString(entry.sessionId);
if (entrySessionId && normalizeQmdSessionStem(entrySessionId) === normalizedStem) {
matches.push(sessionKey);
}
}