Skip to content

[superlog] Downgrade agent stream cleanup Redis timeouts from ERROR to WARN#514

Merged
izadoesdev merged 1 commit into
stagingfrom
codex/superlog-warn-agent-stream-redis-side-effects
Jun 30, 2026
Merged

[superlog] Downgrade agent stream cleanup Redis timeouts from ERROR to WARN#514
izadoesdev merged 1 commit into
stagingfrom
codex/superlog-warn-agent-stream-redis-side-effects

Conversation

@izadoesdev

@izadoesdev izadoesdev commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

  • downgrade agent stream Redis replay side-effect failures to WARN
  • keep broad storage reader/background task failures on ERROR
  • stop the replay writer after the first Redis append failure to avoid per-chunk noise
  • add focused coverage for Redis side-effect WARN vs storage-reader ERROR classification

Supersedes #499 with a clean branch from current staging.

Verification

  • cd apps/api && bunx --bun vitest run src/routes/agent-stream-errors.test.ts
  • bunx ultracite check apps/api/src/routes/agent.ts apps/api/src/routes/agent-stream-errors.ts apps/api/src/routes/agent-stream-errors.test.ts
  • bun run lint
  • bun run check-types
  • bun run test

Summary by cubic

Downgraded Redis side-effect failures in agent streaming (append/clear/done) from ERROR to WARN to cut noisy alerts, while keeping storage reader failures as ERROR. Also stops writing after the first Redis append failure to avoid per-chunk spam and logs one structured warning.

  • Bug Fixes
    • Added warnAgentStreamRedisSideEffect and a payload builder; logs via evlog at WARN with chat/website context.
    • Stop after the first append_stream_chunk failure; only call mark_stream_done if no prior failure.
    • Keep storage_reader failures at ERROR.
    • Added focused tests for severity classification and payload shape.

Written for commit f9ed7e1. Summary will update on new commits.

Review in cubic

@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
databuddy-status Ready Ready Preview, Comment Jun 30, 2026 4:15pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
dashboard Skipped Skipped Jun 30, 2026 4:15pm
documentation Skipped Skipped Jun 30, 2026 4:15pm

@vercel
vercel Bot temporarily deployed to Preview – documentation June 30, 2026 16:15 Inactive
@vercel
vercel Bot temporarily deployed to Preview – dashboard June 30, 2026 16:15 Inactive
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e91efc3b-e8bb-4866-b6b6-e6cbe4273c9b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/superlog-warn-agent-stream-redis-side-effects

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.

@izadoesdev

Copy link
Copy Markdown
Member Author

Clean replacement for #499, rebased onto current staging.

What changed:

  • downgrades only agent stream Redis replay side effects to WARN
  • keeps the broad storage-reader/background task catch on captureError / ERROR
  • stops the replay writer after the first Redis append failure to avoid per-chunk warning noise
  • adds focused coverage for Redis side-effect WARN vs storage-reader ERROR classification

Local verification passed:

  • cd apps/api && bunx --bun vitest run src/routes/agent-stream-errors.test.ts
  • bunx ultracite check apps/api/src/routes/agent.ts apps/api/src/routes/agent-stream-errors.ts apps/api/src/routes/agent-stream-errors.test.ts
  • bun run lint
  • bun run check-types
  • bun run test

@unkey-deploy

unkey-deploy Bot commented Jun 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Unkey Deploy

Name Status Preview Inspect Updated (UTC)
api (preview) Failed Visit Preview Inspect Jun 30, 2026 4:16pm

@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extracts Redis stream side-effect error handling into a dedicated agent-stream-errors module and downgrades those failures from captureError (ERROR) to log.warn (WARN). It also short-circuits the replay writer loop on the first appendStreamChunk failure to suppress per-chunk noise.

  • A new agent-stream-errors.ts module centralises the structured warning payload builder, the severity classifier (getAgentStreamErrorLevel), and the warnAgentStreamRedisSideEffect helper used at every Redis call site in agent.ts.
  • When appendStreamChunk fails, the loop now breaks immediately and markStreamDone is intentionally skipped; broad storageError propagation from the outer IIFE and the onFinish persist path continue to surface as errors via captureError.

Confidence Score: 4/5

Safe to merge — the client-facing stream is unaffected and Redis failures are now quieter in the logs; the main open question is whether replay readers have their own timeouts for the case where markStreamDone is skipped.

The change is narrow and well-tested. The one behavioural shift worth watching is that replay readers no longer receive a done signal when the buffer write fails mid-stream — they must time out on their own. If replay reader timeouts are short or already in place this is harmless; if they are not, hung readers could accumulate silently.

apps/api/src/routes/agent.ts — specifically the markStreamDone skip path and any corresponding Redis replay reader that consumes the done signal.

Important Files Changed

Filename Overview
apps/api/src/routes/agent-stream-errors.ts New utility module extracting Redis-side-effect warning helpers; clean abstraction with proper type exports and structured payload builder.
apps/api/src/routes/agent-stream-errors.test.ts Good focused coverage for payload builder and severity classification; tests all three Redis operation types and the storage_reader branch.
apps/api/src/routes/agent.ts Replaces captureError with warnAgentStreamRedisSideEffect for Redis side effects and adds early-exit on append failure; skipping markStreamDone when the buffer write fails may leave replay readers without a completion signal.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant Agent as agent.ts (IIFE)
    participant Redis
    participant Logger

    Agent->>Redis: appendStreamChunk(chunk)
    alt Redis OK
        Redis-->>Agent: success
        Agent->>Redis: appendStreamChunk(next chunk)
        Agent->>Redis: markStreamDone(streamKey)
    else Redis FAIL
        Redis-->>Agent: throw
        Agent->>Logger: log.warn (warnAgentStreamRedisSideEffect)
        Note over Agent: streamBufferWriteFailed = true, break loop
        Note over Agent: markStreamDone SKIPPED
        Note over Redis: Replay readers receive no done signal
    end

    Agent->>Client: forClient stream continues unaffected

    Agent->>Redis: clearActiveStream (onFinish)
    alt clearActiveStream fails
        Redis-->>Agent: throw
        Agent->>Logger: log.warn (warnAgentStreamRedisSideEffect)
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant Agent as agent.ts (IIFE)
    participant Redis
    participant Logger

    Agent->>Redis: appendStreamChunk(chunk)
    alt Redis OK
        Redis-->>Agent: success
        Agent->>Redis: appendStreamChunk(next chunk)
        Agent->>Redis: markStreamDone(streamKey)
    else Redis FAIL
        Redis-->>Agent: throw
        Agent->>Logger: log.warn (warnAgentStreamRedisSideEffect)
        Note over Agent: streamBufferWriteFailed = true, break loop
        Note over Agent: markStreamDone SKIPPED
        Note over Redis: Replay readers receive no done signal
    end

    Agent->>Client: forClient stream continues unaffected

    Agent->>Redis: clearActiveStream (onFinish)
    alt clearActiveStream fails
        Redis-->>Agent: throw
        Agent->>Logger: log.warn (warnAgentStreamRedisSideEffect)
    end
Loading

Reviews (1): Last reviewed commit: "fix(api): warn on agent stream redis sid..." | Re-trigger Greptile

Comment on lines +1134 to 1147
if (!streamBufferWriteFailed) {
try {
await markStreamDone(streamKey);
} catch (cleanupError) {
warnAgentStreamRedisSideEffect(
cleanupError,
"mark_stream_done",
{
chatId,
websiteId: defaultWebsiteId,
}
);
}
}

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.

P2 Replay readers receive no done signal on buffer write failure

When appendStreamChunk fails and streamBufferWriteFailed is set, the loop exits via break and markStreamDone is skipped. Any active Redis replay reader that is polling for stream chunks and waiting on the done marker will never receive it — it must rely entirely on its own external timeout. If replay readers have long or absent timeouts, they will hang until they are garbage-collected or the connection drops. This is the intentional trade-off described in the PR, but it's worth confirming the replay reader side has an appropriate deadline in place.

Comment on lines +12 to +16
export function getAgentStreamErrorLevel(
failure: AgentStreamBackgroundFailure
): "error" | "warn" {
return failure === "storage_reader" ? "error" : "warn";
}

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.

P2 getAgentStreamErrorLevel is exported and tested but never called at runtime

No production call site invokes this function — warnAgentStreamRedisSideEffect hardcodes log.warn, and the storage_reader path in agent.ts still calls captureError directly. The classification is correct and verified by tests, but the function is decoupled from the actual dispatching logic. If a new failure kind is added and a caller forgets to also update the dispatch code, the tests would still pass while the wrong log level is emitted.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@izadoesdev
izadoesdev merged commit e7236aa into staging Jun 30, 2026
19 checks passed
@izadoesdev
izadoesdev deleted the codex/superlog-warn-agent-stream-redis-side-effects branch June 30, 2026 16:20
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