Thank you to everyone who's shared feedback, reported problems and suggested improvements. A lot has gone into Pinchflat-ngx since the last release, and your help keeps finding the small issues that are easy to miss. I feel we're getting closer to the level of stability I want for the project, with fewer rough edges in everyday use.
PaulEins asked for a way to watch downloaded videos for later changes, and skoch13 asked for retention defaults that could be shared across sources. I've brought both requests into this release.
Thanks also to Plutoaurus for reporting repeated filter retries, iNaD for the Music/mobile URL reproduction, and Jory Irving for tracing the cookie, thumbnail and PostgreSQL failures. Those detailed reports helped turn the fixes below into reproducible checks. Thanks to funar for independently reporting the PostgreSQL size limit in #190; the fix is included here.
Thanks to LunarLaurus for adding native yt-dlp plugin management in #179, and silverwzw for fixing the daylight-saving date calculation in #185, included with regression tests in #187.
Starting with this release, version numbers will use year.month.patch. For example, 2026.11.0 identifies November's release, with follow-up fixes numbered 2026.11.1, 2026.11.2 and so on. The final number counts patches rather than the day of publication.
Before upgrading
This release adds database migrations. Downgrading by switching back to the previous image is not supported against the upgraded state; retain a coherent pre-upgrade recovery point if you need to return to 2026.10.20. PostgreSQL may hold a media-table lock while widening file sizes. Allow startup migrations to finish.
Watch windows are off by default and apply to newly completed downloads. Saved originals can require extra disk space, and replacement/recovery work can need temporary copies too. Back up the database, configuration and media together, including .pinchflat-originals when it exists. Upgrade and rollback, watch backups and recovery.
Review retention when changing a profile default or assigning a source to a different profile. Blank source retention now inherits the profile; 0 explicitly disables age-based expiry for that source. Profile changes can make existing downloads eligible for cleanup. The separate publication-date cutoff still applies.
If an earlier yt-dlp run removed login cookies, upload fresh cookies after upgrading and retry the affected downloads. The new isolation preserves uploaded cookies but cannot restore an expired or previously lost session. Valid access to restricted videos is still required. Cookie settings and recovery.
Highlights
Watch downloaded videos for changes
Set a watch window on a media profile or override it for a source. After a new download completes, Pinchflat-ngx checks remote duration and visibility during that fixed window, records confirmed changes and queues notifications to configured destinations. Existing downloads are not enrolled automatically.
Before a protected replacement, the first completed local artifact and available associated files are preserved and verified. Watch details show history, check results and saved-original access. Suspected changes and recovery holds can stop replacement or deletion; ending watch protection requires explicit confirmation.
These checks do not compare remote content byte by byte: title-only changes and equal-duration edits are not detected. Provider failures are inconclusive rather than proof of deletion. Watch guide. (#173)
Manage yt-dlp plugins in Settings
Upload a .zip, .whl or .egg archive, or install from an allowed direct URL under Settings > yt-dlp > Plugins. URL-installed plugins can be updated on demand. Each package has a configuration editor with its bundled README, and packages and configuration persist on the config volume.
Plugins can add extractors or postprocessors, but they run arbitrary Python inside the container. Install only trusted code. Archive installation does not install Python dependencies, and postprocessors still need --use-postprocessor NAME. Plugin import failures appear in logs and can alert Apprise, with concurrent reports sharing a cooldown. Plugin setup, limits and recovery. (#179)
Find individual downloads and browse each source's videos
Sources now separates Channels & playlists from Individual videos, so Paste URL downloads are easier to find. Each source also has a Videos tab with list and grid views of downloaded records. Existing records and files are reused, and switching layouts does not start downloads. Individual videos, source views. (#171, #175)
Set retention once on a media profile
Media profiles can supply a retention default for their sources, including sources created by individual-video intake. Leave a source blank to inherit, set a positive number to override, or use 0 to disable age-based expiry. The source form previews the effective value, and source summaries show where it comes from. Retention uses download time; publication-date cutoff cleanup remains separate. Retention and protection. (#160, #166)
Fixes and security
- Ecto security update: Ecto 3.14.3 fixes unbounded query-cache growth involving interpolated JSON paths, splice lists and constants (CVE-2026-118391). Upstream fix. (#188)
- Cutoff dates across daylight-saving changes: relative cutoff presets now subtract calendar days from the configured local date, avoiding a one-day error around clock changes. Publication-date filtering and cleanup rules are unchanged. (#185, #187)
- More reliable indexing: full-channel indexing now reports and retries real tab failures instead of treating partial success as a completed run. Diagnostics tabs and mobile job controls are corrected. Healthy long-running jobs are no longer requeued solely because of the removed 30-minute Lifeline rule. Indexing health, Diagnostics. (#159)
- Authentication that survives the thumbnail step: cookie-using commands work from private temporary copies. With When Needed, an internal thumbnail authentication error gets one cookie retry, allowing an authenticated media download to finish. Disabled cookies remain disabled. Download settings. (#180, #184)
- Large PostgreSQL downloads and transfers: recorded media sizes now use 64 bits, and byte totals remain integers across the homepage, source lists, statistics and migration review. Files larger than 2 GiB can be recorded without overflowing the old column. Transfer exceptions log a safe error type/code. SQLite keeps its native 64-bit sizes. Migration guide. (#182)
- Stop repeated filter skips: confirmed yt-dlp filter rejections become permanent failures. After changing the filter, use Force Retry for the affected item. This does not claim that every unrelated missing-output-file failure is fixed. Download recovery. (#163)
- Source URL handling: Music and mobile YouTube source URLs are accepted. Empty Watch Later sources can be inspected when YouTube supplies collection metadata; use cookies from the owning account and All Operations. YouTube may still require a video in the playlist before returning details. Source setup. (#174, #177)
- Backup access: completed PostgreSQL dumps download from the standalone Backups page and existing saved links. Migration/settings navigation is corrected. Backups and restore. (#169)
Other changes
- Discord webhook notifications use Apprise embed formatting by default while preserving explicit format options. Other providers keep their existing formatting. Notifications. (#171)
- The interface uses system fonts without a Google Fonts request. (#170)
- Dependency updates include security patches for PlugCrypto and Assent, alongside server, SQLite, frontend and build-tool updates. Stable image publication runs once from the published release event.
Container images
SQLite and PostgreSQL images are now available at the versioned tags below and their moving aliases.
| Database | Versioned image | Moving tag |
|---|---|---|
| SQLite | ghcr.io/thebadfella/pinchflat-ngx:2026.11.0
| latest
|
| PostgreSQL | ghcr.io/thebadfella/pinchflat-ngx:2026.11.0-postgres
| latest-postgres
|
Both database images include AMD64 and ARM64 manifests. The release build passed, and the published AMD64 images passed smoke checks with isolated fixture data. ARM64 runtime remains unverified.
For pinned installations, update the image tag first. Pull and recreate the application service using your existing Compose setup, then check startup migrations, health and Diagnostics. When transferring from SQLite to PostgreSQL, upgrade SQLite to the matching release before stopping it and preparing the retained source. Upgrading, transfer guide.
Full changelog: 2026.10.20...2026.11.0.