- Fix zone colors not matching across profiles by falling back to base zone color when profile zone data lacks a color field
- Use base_config for base-layer values in masks/zones view so profile-merged values don't pollute the base config editing view
- Handle zones separately in profile manager snapshot/restore since ZoneConfig requires special serialization (color as private attr, contour generation)
- Inherit base zone color and generate contours for profile zone overrides in profile manager
When a profile is active, the in-memory config contains effective
(profile-merged) values. The settings UI was displaying these merged
values even when the "Base Config" view was selected.
Backend: snapshot pre-profile base configs in ProfileManager and expose
them via a `base_config` key in the /api/config camera response when a
profile is active. The top-level sections continue to reflect the
effective running config.
Frontend: read from `base_config` when available in BaseSection,
useConfigOverride, useAllCameraOverrides, and prepareSectionSavePayload.
Include formData labels in Object/Audio switches widgets so that labels
added only by a profile override remain visible when editing that profile.
parse_preset_input() uses input[len(_user_agent_args) + 1] to find
the FPS placeholder, but preset-http-jpeg-generic does not include
_user_agent_args at the start of its list (only preset-http-mjpeg-generic
does). The FPS placeholder '{}' is at index 1, not index 3.
This means the detect_fps value overwrites '-1' (the stream_loop
argument) instead of the '{}' FPS placeholder, so the preset always
uses the literal string '{}' as the framerate.
When hwaccel_args is a list (not a preset string), the fallback in
parse_preset_hardware_acceleration_encode() calls
arg_map["default"].format(input, output) with only 2 positional args.
But PRESETS_HW_ACCEL_ENCODE_BIRDSEYE["default"] contains {0}, {1}, {2}
expecting ffmpeg_path as the first arg.
This causes IndexError: Replacement index 2 out of range for size 2
which crashes create_config.py on every go2rtc start, taking down
all camera streams.
Pass ffmpeg_path as the first argument to match the preset template.
In BirdsEyeFrameManager.__init__(), the numpy slice that copies the
custom logo (transparent_layer from custom.png alpha channel) onto
blank_frame has shape[0] and shape[1] swapped:
blank_frame[y:y+shape[1], x:x+shape[0]] = transparent_layer
shape[0] is rows (height) and shape[1] is cols (width), so the row
range needs shape[0] and the column range needs shape[1]:
blank_frame[y:y+shape[0], x:x+shape[1]] = transparent_layer
The bug is masked for square images where shape[0]==shape[1]. For
non-square images (e.g. 1920x1080), it produces:
ValueError: could not broadcast input array from shape (1080,1920)
into shape (1620,1080)
This silently kills the birdseye output process -- no frames are
written to the FIFO pipe, go2rtc exec ffmpeg times out, and the
birdseye restream shows a black screen with no errors in the UI.
In both expire_snapshots() and expire_clips(), the expired_events
query uses .iterator() for lazy evaluation, but the very next line
calls list(expired_events) inside an f-string for debug logging.
This consumes the entire iterator, so the subsequent for loop that
deletes media files from disk iterates over an exhausted iterator
and processes zero events.
Snapshots and clips for removed cameras are never deleted from disk,
causing gradual disk space exhaustion.
Materialize the iterator into a list before logging so both the
debug message and the cleanup loop use the same data.
The cosine similarity calculation is guarded by:
if not np.any(np.linalg.norm(velocities, axis=1))
This enters the block when ALL velocity norms are zero, then divides
by those zero norms. The condition should check that all norms are
non-zero before computing cosine similarity:
if np.all(np.linalg.norm(velocities, axis=1))
Also fixes debug log that shows average_velocity[0] for both x and y
velocity components (second should be average_velocity[1]).
The connect() function creates a WebSocket but never stores the
reference. The useEffect cleanup only closes the RTCPeerConnection
via pcRef, leaving the WebSocket open.
Each time the component re-renders with changed deps (camera switch,
playback toggle, microphone toggle), a new WebSocket is created
without closing the previous one. This leaks connections until the
browser garbage-collects them or the server times out.
Store the WebSocket in a ref and close it in the cleanup function.
cv2.imread with IMREAD_UNCHANGED loads the image as-is, but the code
unconditionally indexes channel 3 (birdseye_logo[:, :, 3]) assuming
RGBA format. This crashes with IndexError for:
- Grayscale PNGs (2D array, no channel dimension)
- RGB PNGs without alpha (3 channels, no index 3)
- Fully transparent PNGs saved as grayscale+alpha (2 channels)
Handle all image formats:
- 2D (grayscale): use directly as luminance
- 4+ channels (RGBA): extract alpha channel (existing behavior)
- 3 channels (RGB/BGR): convert to grayscale
Also fixes the shape[0]/shape[1] swap in the array slice that breaks
non-square images (related to #6802, #7863).
In BirdsEyeFrameManager.update(), the exception handler on line 756
resets self.active_cameras to [] (a list), but it is initialized as
set() and compared as a set throughout the rest of the code.
Since set() \!= [] evaluates to True even though both are empty, the
next call to update_frame() will incorrectly detect a layout change
and trigger an unnecessary frame rebuild after every exception.
escape_special_characters() returns a ValueError object instead of
raising it when the input path exceeds 1000 characters. The exception
object gets used as a string downstream instead of triggering error
handling.
When an existing tracked object's label or stationary status changes
(e.g. sub_label assignment from face recognition), the update handler
declares a new const newObjects that shadows the outer let newObjects.
The label and stationary mutations apply to the inner copy, but
handleSetObjects on line 148 reads the outer variable which was never
mutated. The update is silently discarded.
Remove the inner declaration so mutations apply to the outer variable
that gets passed to handleSetObjects.
gpu <= len(self._valid_gpus) should be gpu < len(self._valid_gpus).
The list is zero-indexed, so requesting gpu index equal to the list
length causes an IndexError. For example, with 2 valid GPUs (indices
0 and 1), requesting gpu=2 passes the check (2 <= 2) but
self._valid_gpus[2] is out of bounds.
test_maintainer was injecting MagicMock() into sys.modules["frigate.config.camera.updater"] at module load time and never restoring it. When the profile tests later imported CameraConfigUpdateEnum and CameraConfigUpdateTopic from that module, they got mock objects instead of the real dataclass/enum, so equality comparisons always failed
* fix double scrollbar in debug replay
* always hide ffmpeg cpu warnings for replay cameras
* add slovenian
* fix motion previews on safari and ios
match the logic used in ScrubbablePreview for manually stepping currentTime at the correct rate
* prevent motion recalibration when opening motion tuner
* add shm frame lifetime calculation and update UI for shared memory metrics
* consistent sizing on activity indicator in save buttons
* fix offline overlay overflowing on mobile when in grid mode
The /config API was dumping profile overrides with model_dump() which included
all Pydantic defaults. When the frontend merged these over
the camera's base config, explicitly-set base values were
lost. Now profile overrides are re-dumped with exclude_unset=True so only
user-specified fields are returned.
Also fixes the Save All path generating spurious deletion markers for
restart-required fields that are hidden during profile
editing but not excluded from the raw data sanitization in
prepareSectionSavePayload.
asyncio.SubprocessError does not exist — Python's asyncio module has no
such class. The correct exception is subprocess.SubprocessError, which
is available via the existing `import subprocess as sp` alias already
present in this file.
The invalid exception reference causes the except clause to raise a
NameError rather than catching the intended exception.
- Add ProfileDefinitionConfig type and profiles field to FrigateConfig
- Use ProfilesApiResponse type with friendly_name support throughout
- Replace Record<string, unknown> with proper JsonObject/JsonValue types
- Add profile creation form matching zone pattern (Zod + NameAndIdFields)
- Add pencil icon for renaming profile friendly names in ProfilesView
- Move Profiles menu item to first under Camera Configuration
- Add activity indicators on save/rename/delete buttons
- Display friendly names in CameraManagementView profile selector
- Fix duplicate colored dots in management profile dropdown
- Fix i18n namespace for overridden base config tooltips
- Move profile override deletion from dropdown trash icon to footer
button with confirmation dialog, matching Reset to Global pattern
- Remove Add Profile from section header dropdown to prevent saving
camera overrides before top-level profile definition exists
- Clean up newProfiles state after API profile deletion
- Refresh profiles SWR cache after saving profile definitions