forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFC-definition-time-mutable-default-shared-across-calls.json
More file actions
9 lines (9 loc) · 1.96 KB
/
Copy pathFC-definition-time-mutable-default-shared-across-calls.json
File metadata and controls
9 lines (9 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
{
"schema_version": 1,
"id": "FC-definition-time-mutable-default-shared-across-calls",
"violated_contract": "A parameter whose default is a mutable literal -- `callback_data: Dict[str, Any] = {}`, `keywords: List[str] = []` -- is bound ONCE, when the `def` executes at import time, not per call. Every caller that omits the argument therefore operates on the same object, so any in-place write the body performs (`callback_data['error'] = ...`, `.append(...)`) persists into the next defaulted call and outlives the request that made it. The trap is that the declaration reads as a per-call empty value, and the code is correct for as long as every call site happens to pass the argument explicitly: the defect is latent, invisible in review of the function itself, and armed by the next caller who reasonably relies on the default. On a per-request server path this is a cross-request state leak, not merely stale data -- in `execute_chat_stream` the setup-timeout branch writes `error`, `route` and `answer`, so a later defaulted call reaches its handler already carrying a previous request's answer text.",
"canonical_prevention": "Declare the parameter `Optional[...] = None` and materialize the mutable inside the body (`if x is None: x = {}`), so each call owns its object. Reserve mutable defaults for values that are provably never mutated, and prefer an immutable default (`()`, `frozenset()`, `None`) when the body only reads. When fixing one instance, sweep the rest of the package for the same shape rather than fixing only the reported call: the class propagates by copy-paste between sibling handlers, which is exactly how the router copy at `utils/retrieval/graph.py` survived the fix to `utils/agent.py` in #12094. `ruff --select B006` flags the declaration mechanically; the judgement it cannot make is whether the body mutates the shared object, which is what separates a defect from a smell.",
"evidence_prs": [12094],
"scope_hints": ["backend/**"],
"status": "open"
}