Skip to content

Commit f01d580

Browse files
committed
fix(memory-core): suppress WARN for narrative cleanup scope errors
deleteSession during dreaming cleanup fails with "missing scope: operator.admin" when the cron session lacks admin permissions. This is expected best-effort behavior, but logged at WARN, which floods logs after every dreaming cycle. Downgrade to debug when the error matches /missing scopes?:/i. Also add optional debug field to the Logger type so callers without a debug method (like dreaming-phases) compile cleanly.
1 parent c54464a commit f01d580

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

extensions/memory-core/src/dreaming-narrative.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ describe("generateAndAppendDreamNarrative", () => {
573573

574574
function createMockLogger() {
575575
return {
576+
debug: vi.fn(),
576577
info: vi.fn(),
577578
warn: vi.fn(),
578579
error: vi.fn(),
@@ -678,6 +679,27 @@ describe("generateAndAppendDreamNarrative", () => {
678679
);
679680
});
680681

682+
it("logs debug (not warn) when deleteSession fails due to missing scope", async () => {
683+
const workspaceDir = await createTempWorkspace("openclaw-dreaming-narrative-");
684+
const subagent = createMockSubagent("");
685+
subagent.deleteSession.mockRejectedValue(new Error("missing scope: operator.admin"));
686+
const logger = createMockLogger();
687+
688+
await generateAndAppendDreamNarrative({
689+
subagent,
690+
workspaceDir,
691+
data: { phase: "light", snippets: ["some memory"] },
692+
logger,
693+
});
694+
695+
expect(logger.warn).not.toHaveBeenCalledWith(
696+
expect.stringContaining("narrative session cleanup failed"),
697+
);
698+
expect(logger.debug).toHaveBeenCalledWith(
699+
expect.stringContaining("narrative session cleanup skipped for light phase"),
700+
);
701+
});
702+
681703
it("handles subagent error gracefully", async () => {
682704
const workspaceDir = await createTempWorkspace("openclaw-dreaming-narrative-");
683705
const subagent = createMockSubagent("");

extensions/memory-core/src/dreaming-narrative.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export type NarrativePhaseData = {
5151
};
5252

5353
type Logger = {
54+
debug?: (message: string) => void;
5455
info: (message: string) => void;
5556
warn: (message: string) => void;
5657
error: (message: string) => void;
@@ -932,9 +933,18 @@ export async function generateAndAppendDreamNarrative(params: {
932933
try {
933934
await params.subagent.deleteSession({ sessionKey });
934935
} catch (cleanupErr) {
935-
params.logger.warn(
936-
`memory-core: narrative session cleanup failed for ${params.data.phase} phase: ${formatErrorMessage(cleanupErr)}`,
937-
);
936+
const errMsg = formatErrorMessage(cleanupErr);
937+
// Cleanup is best-effort; permission errors are expected when the cron
938+
// session lacks operator.admin scope — log at debug to avoid noise.
939+
if (/missing scopes?:/i.test(errMsg)) {
940+
params.logger.debug?.(
941+
`memory-core: narrative session cleanup skipped for ${params.data.phase} phase (insufficient scope): ${errMsg}`,
942+
);
943+
} else {
944+
params.logger.warn(
945+
`memory-core: narrative session cleanup failed for ${params.data.phase} phase: ${errMsg}`,
946+
);
947+
}
938948
}
939949

940950
await scrubDreamingNarrativeArtifacts(params.logger).catch((scrubErr: unknown) => {

0 commit comments

Comments
 (0)