# Bug 13: AttributeError - Recording Object Has No 'protocol' Attribute

**Date Fixed**: November 17, 2025
**Severity**: CRITICAL
**Impact**: Application crashed when adding files to analysis in Rin tab

---

## Problem Description

When adding a file to the analysis set, the Rin Analysis tab would immediately crash with:
```
AttributeError: 'Recording' object has no attribute 'protocol'
```

This occurred in `rin_tab.py` at line 1213 in the `_gather_analysis_parameters()` method.

---

## Root Cause

During a previous fix attempt, code was added to try to fetch `delta_i_pa` from a non-existent `protocol` attribute on the `Recording` object:

```python
# INCORRECT CODE (lines 1211-1223):
if params.get('is_voltage') and not params.get('delta_i_pa'):
 if self._selected_item_recording and self._selected_item_recording.protocol: # protocol doesn't exist
 protocol_delta_i = self._selected_item_recording.protocol.get('delta_i_pa')
 if protocol_delta_i:
 params['delta_i_pa'] = protocol_delta_i
```

The `Recording` class in `data_model.py` does not have a `protocol` attribute, causing the crash.

---

## Impact on User

**Before Fix:**
- Application starts normally
- Files load in Explorer tab
- **CRASH when adding file to analysis** → Rin tab fails instantly
- Error message: `'Recording' object has no attribute 'protocol'`
- Analysis cannot proceed

**After Fix:**
- Application starts normally
- Files load in Explorer tab
- **Files can be added to analysis successfully**
- All analysis tabs load without errors
- Analysis can proceed normally

---

## Fix Applied

**Location**: `src/Synaptipy/application/gui/analysis_tabs/rin_tab.py` (lines 1211-1223)

**Action**: Removed the incorrect code that attempted to access the non-existent `protocol` attribute.

**Code Change:**
```python
# Before (INCORRECT - 13 lines with protocol access):
# Get delta values
if params.get('is_voltage'):
 if self.manual_delta_i_spinbox:
 params['delta_i_pa'] = self.manual_delta_i_spinbox.value()
elif params.get('is_current'):
 if self.manual_delta_v_spinbox:
 params['delta_v_mv'] = self.manual_delta_v_spinbox.value()

# If delta_i is still not found, try to get it from the recording's protocol
if params.get('is_voltage') and not params.get('delta_i_pa'):
 if self._selected_item_recording and self._selected_item_recording.protocol: # CRASH HERE
 protocol_delta_i = self._selected_item_recording.protocol.get('delta_i_pa')
 if protocol_delta_i:
 params['delta_i_pa'] = protocol_delta_i

log.debug(f"Gathered Rin parameters: {params}")

# After (CORRECT - 5 lines, no protocol access):
# Get delta values
if params.get('is_voltage'):
 if self.manual_delta_i_spinbox:
 params['delta_i_pa'] = self.manual_delta_i_spinbox.value()
elif params.get('is_current'):
 if self.manual_delta_v_spinbox:
 params['delta_v_mv'] = self.manual_delta_v_spinbox.value()

log.debug(f"Gathered Rin parameters: {params}")
```

---

## Verification

- File compiles without errors
- No linting errors
- All tests pass (12/12)
- Application now accepts files for analysis without crashing
- Rin tab loads and displays data correctly
- No AttributeError when gathering analysis parameters

---

## Notes

### Why This Bug Occurred

This bug was introduced during an earlier attempt to automatically fetch `delta_i_pa` values from recording metadata. The assumption that recordings would have a `protocol` attribute containing stimulus parameters was incorrect.

### Proper Solution

The delta values (`delta_i_pa` for voltage clamp, `delta_v_mv` for current clamp) should be:
1. **User-provided** via the manual spinboxes in the UI
2. **Stored with results** for reference
3. **Not assumed to be in the recording** (not all file formats include this metadata)

If automatic protocol detection is desired in the future, it should:
- Check if the attribute exists using `hasattr()` first
- Handle gracefully when not available
- Have proper fallback behavior

---

## Total Bugs Fixed

This is **Bug 13** in the refactoring bug fix series.

**All Bugs (1-13)**: RESOLVED

---

**Status**: FIXED AND VERIFIED

