[fix]: sanitize ErrorDetailsParsed so raw payloads honor disable_content_logging - #4873
Conversation
…ent_logging The logging plugin serialized a sanitized copy of the provider error into entry.ErrorDetails but then stored the original, unsanitized error in entry.ErrorDetailsParsed. logstore's SerializeFields (run from the BeforeCreate GORM hook on every insert) re-serializes ErrorDetailsParsed and overwrites ErrorDetails, so the sanitization was defeated: with content logging or raw storage disabled, error rows still persisted the full raw request/response payloads attached to the error. The queue entry also pinned those payloads in memory until flush. Store the sanitized error in both fields via a shared helper (applyErrorDetailsToEntry) at every direct assignment site, including the streaming-output path and the MCP tool log path. Behavior with content logging + raw storage enabled is unchanged (the original error is passed through). Note: updateLogEntry's UpdateLogData.ErrorDetails path is not covered here because shouldStoreRaw is not in scope there; flagged in the PR. Affected packages/files: - plugins/logging/main.go - plugins/logging/operations.go - plugins/logging/sanitize_test.go - plugins/logging/changelog.md
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughLogging now stores sanitized error details consistently in both parsed and serialized fields across LLM, MCP, and streaming error paths. Tests cover sanitized, raw-enabled, nil, and MCP cases, and the changelog notes the fix. ChangesSanitize ErrorDetailsParsed
Estimated code review effort: 3 (Moderate) | ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" 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. Comment |
Adds applyErrorDetailsToMCPEntry (MCPToolLog counterpart of applyErrorDetailsToEntry) so the MCP error path serializes the sanitized error into ErrorDetails at assignment time instead of deferring entirely to the BeforeCreate hook, matching the LLM paths' pool-safety pattern. Per review feedback. Affected packages/files: - plugins/logging/main.go - plugins/logging/sanitize_test.go
|
|
…ent_logging (maximhq#4873) * [fix]: sanitize ErrorDetailsParsed so raw payloads honor disable_content_logging The logging plugin serialized a sanitized copy of the provider error into entry.ErrorDetails but then stored the original, unsanitized error in entry.ErrorDetailsParsed. logstore's SerializeFields (run from the BeforeCreate GORM hook on every insert) re-serializes ErrorDetailsParsed and overwrites ErrorDetails, so the sanitization was defeated: with content logging or raw storage disabled, error rows still persisted the full raw request/response payloads attached to the error. The queue entry also pinned those payloads in memory until flush. Store the sanitized error in both fields via a shared helper (applyErrorDetailsToEntry) at every direct assignment site, including the streaming-output path and the MCP tool log path. Behavior with content logging + raw storage enabled is unchanged (the original error is passed through). Note: updateLogEntry's UpdateLogData.ErrorDetails path is not covered here because shouldStoreRaw is not in scope there; flagged in the PR. Affected packages/files: - plugins/logging/main.go - plugins/logging/operations.go - plugins/logging/sanitize_test.go - plugins/logging/changelog.md * [fix]: serialize MCP error details immediately via parallel helper Adds applyErrorDetailsToMCPEntry (MCPToolLog counterpart of applyErrorDetailsToEntry) so the MCP error path serializes the sanitized error into ErrorDetails at assignment time instead of deferring entirely to the BeforeCreate hook, matching the LLM paths' pool-safety pattern. Per review feedback. Affected packages/files: - plugins/logging/main.go - plugins/logging/sanitize_test.go --------- Co-authored-by: Akshay Deo <akshay@akshaydeo.com>
…ent_logging (maximhq#4873) * [fix]: sanitize ErrorDetailsParsed so raw payloads honor disable_content_logging The logging plugin serialized a sanitized copy of the provider error into entry.ErrorDetails but then stored the original, unsanitized error in entry.ErrorDetailsParsed. logstore's SerializeFields (run from the BeforeCreate GORM hook on every insert) re-serializes ErrorDetailsParsed and overwrites ErrorDetails, so the sanitization was defeated: with content logging or raw storage disabled, error rows still persisted the full raw request/response payloads attached to the error. The queue entry also pinned those payloads in memory until flush. Store the sanitized error in both fields via a shared helper (applyErrorDetailsToEntry) at every direct assignment site, including the streaming-output path and the MCP tool log path. Behavior with content logging + raw storage enabled is unchanged (the original error is passed through). Note: updateLogEntry's UpdateLogData.ErrorDetails path is not covered here because shouldStoreRaw is not in scope there; flagged in the PR. Affected packages/files: - plugins/logging/main.go - plugins/logging/operations.go - plugins/logging/sanitize_test.go - plugins/logging/changelog.md * [fix]: serialize MCP error details immediately via parallel helper Adds applyErrorDetailsToMCPEntry (MCPToolLog counterpart of applyErrorDetailsToEntry) so the MCP error path serializes the sanitized error into ErrorDetails at assignment time instead of deferring entirely to the BeforeCreate hook, matching the LLM paths' pool-safety pattern. Per review feedback. Affected packages/files: - plugins/logging/main.go - plugins/logging/sanitize_test.go --------- Co-authored-by: Akshay Deo <akshay@akshaydeo.com>
Summary
The logging plugin serialized a sanitized copy of the provider error into
entry.ErrorDetails, but stored the original, unsanitized error inentry.ErrorDetailsParsed.logstore.Log.SerializeFields— run from theBeforeCreateGORM hook on every insert — re-serializesErrorDetailsParsedand overwritesErrorDetails, and nothing on the write path clears the parsed field first. The sanitization was therefore defeated end to end: withdisable_content_logging: true(or raw storage off), error rows still persisted the full raw request/response payloads attached to the error, and each queued write entry pinned those payloads in memory until batch flush.Changes
plugins/logging/main.go— new helperapplyErrorDetailsToEntrythat sanitizes once and stores the same sanitized copy in bothErrorDetailsandErrorDetailsParsed; the four directbifrostErrassignment sites now use it. The MCP tool log path (PostMCPHook) sanitizes itsMCPToolLog.ErrorDetailsParsedassignment the same way.plugins/logging/operations.go—applyStreamingOutputToEntry(which serialized the unsanitized error into both fields) now uses the helper.plugins/logging/sanitize_test.go— regression tests that round-trip throughlogstore.Log.SerializeFields(the actual overwrite path): raw markers must not survive with content logging disabled, must survive when explicitly enabled, and a nil error is a no-op.plugins/logging/changelog.md— changelog entry.Behavior with content logging + raw storage both enabled is unchanged —
sanitizeErrorForLoggingpasses the original through in that configuration.Not covered (maintainer input wanted)
updateLogEntry'sUpdateLogData.ErrorDetailspath (operations.go) has the same shape, butshouldStoreRawis not in scope there (the function only receivescontentLoggingEnabled). Rather than guess at threading the flag through, I left it and flagged it in #4872 — happy to extend this PR if you point me at the preferred plumbing.Type of change
Affected areas
How to test
Full
go test -raceon plugins/logging passes;gofmtclean.Breaking changes
None. Configurations with raw persistence enabled see identical output; configurations with it disabled now get what the config promised.
Related issues
Closes #4872
Security considerations
This is primarily a data-privacy fix: prevents raw request/response content from being persisted to the logs store when the operator has disabled content logging.
Checklist
plugins/logging/changelog.md)[type]: descriptionformat