ref(seer): Filter private fields from explorer chat API response#113125
ref(seer): Filter private fields from explorer chat API response#113125
Conversation
The explorer chat GET endpoint was forwarding the full SeerRunState from Seer to users, exposing internal fields like usage/cost data, metadata, and coding agent state. Additionally, all models used extra="allow" which let any undeclared fields from Seer leak through. Change extra to "ignore" so undeclared fields are dropped at parse time, and mark internal fields (usage, metadata, coding_agents) with Field(exclude=True) so they are omitted from .dict() but still accessible as attributes for internal callers like autofix. Also declares fields the frontend consumes that were previously only passing through as extras: owner_user_id, todos, tool_links, tool_results, thinking_content, and ToolCall.id. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 28e56e6. Configure here.
| diff: str = "" | ||
|
|
||
| class Config: | ||
| extra = "allow" |
There was a problem hiding this comment.
FilePatch still allows extra fields to leak through
Low Severity
FilePatch retains extra = "allow" while every other model in the chat response serialization chain (ExplorerFilePatch, MemoryBlock, SeerRunState, etc.) was changed to extra = "ignore". Since FilePatch is nested inside ExplorerFilePatch which appears in MemoryBlock.file_patches and MemoryBlock.merged_file_patches, any undeclared fields Seer attaches to file patch objects can still leak through state.dict() to the API response.
Reviewed by Cursor Bugbot for commit 28e56e6. Configure here.
There was a problem hiding this comment.
This was intentional since there were some nested fields that were a bit painful to add types for right now. Seems fine to keep as-is for the short term, can follow up.


The explorer chat GET endpoint was forwarding the full
SeerRunStatefrom Seer to users viastate.dict(), exposing internal fields and metadata. All models also usedextra = "allow"which let any undeclared fields from Seer leak through to the response.Two changes:
extra = "ignore"on models used in the chat response, so undeclared fields from Seer are dropped at parse time rather than leaking through.dict()Field(exclude=True)on some fields so they're omitted from.dict()but still accessible as attributes for internal callers (autofix, night shift, etc.)Also declares fields the frontend consumes that were previously only passing through as Pydantic extras:
owner_user_id,todos,tool_links,tool_results,thinking_content, andToolCall.id.Related: https://github.com/getsentry/seer/pull/5803 — this change on the Sentry side makes the Seer-side stripping of fields unnecessary for the chat endpoint.