roboflow/supervision · error · Exception
Cannot append to CSV: The file '{self.file_name}' is not ope
Error message
Cannot append to CSV: The file '{self.file_name}' is not open. What it means
CSVSink raises this generic Exception from append() when its internal csv writer is None, i.e. the sink is not inside its opened context. CSVSink opens the file lazily via the context-manager protocol (__enter__), so append() is only valid inside a `with CSVSink(...) as sink:` block.
Source
Thrown at src/supervision/detection/tools/csv_sink.py:214
parsed_rows.append(row)
return parsed_rows
def append(
self, detections: Detections, custom_data: dict[str, Any] | None = None
) -> None:
"""
Append detection data to the CSV file.
Args:
detections: The detection data.
custom_data: Custom data to include. Scalars, dictionaries, and
other non-sequence values are broadcast to every detection in
this batch. NumPy arrays, lists, and tuples with length equal
to ``len(detections)`` are sliced per detection; other lists
and tuples are broadcast unchanged.
"""
if not self.writer:
raise Exception(
f"Cannot append to CSV: The file '{self.file_name}' is not open."
)
field_names = CSVSink.parse_field_names(detections, custom_data)
if not self.header_written:
self.field_names = field_names
self.writer.writerow(field_names)
self.header_written = True
if field_names != self.field_names:
logger.warning(
"Field names do not match the header. Expected: %s, given: %s",
self.field_names,
field_names,
)
parsed_rows = CSVSink.parse_detection_data(detections, custom_data)
for row in parsed_rows:
self.writer.writerow(View on GitHub (pinned to 7f254d9784)
Solutions
- Wrap usage in the context manager: with CSVSink('out.csv') as sink: sink.append(detections).
- Keep the entire detection loop inside the with block so append always has an open writer.
- If appending from multiple places, open the sink once and pass it down while the context is still active.
- Do not call append() after __exit__; create a new CSVSink for a new session.
Example fix
# before
sink = CSVSink("out.csv")
sink.append(detections) # Exception: file is not open
# after
with CSVSink("out.csv") as sink:
for frame in video:
detections = model(frame)
sink.append(detections) Defensive patterns
Strategy: try-catch
Validate before calling
if getattr(sink, "writer", None) is None:
raise RuntimeError("CSVSink not open; use 'with CSVSink(...) as sink:'")
sink.append(detections) Try / catch
try:
sink.append(detections)
except Exception as exc:
if "not open" in str(exc):
logger.error("CSVSink used outside its context manager")
raise
raise Prevention
- Always open CSVSink via 'with' and keep the processing loop inside the block.
- Structure code so the sink is passed down while its context is active.
- Create a new sink per output session; never reuse one after __exit__.
When it happens
Trigger: Creating sink = CSVSink('out.csv') and calling sink.append(detections) without entering the with block; or calling append() after the with block has exited (file already closed).
Common situations: Migrating code that assumed the constructor opens the file (older examples or other sinks like JSONSink behave differently); storing the sink on a class and appending from another method after the context exited; reusing a sink across video loops where only the first loop is inside the with.
Related errors
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/d1d60fff46db60b9.
Report an issue: GitHub.