Automated Plex trash management tool that validates filesystem state before emptying library trash. Prevents accidental deletion when using network-mounted storage.
mkdir dumpsterr && cd dumpsterr
curl -fsSL https://raw.githubusercontent.com/chase-roohms/dumpsterr/refs/heads/main/docker-compose/quickstart.sh | bash
# Edit config.yml and .env
docker compose up -dWhen Plex runs on a different host than your media storage (NFS, SMB, etc.), network interruptions can cause mount failures. If Plex scans while mounts are down, it marks all media as deleted and removes them from your library. Re-mounting triggers a full rescan and metadata rebuild.
Plex's "fix" for this is to disable "Empty trash automatically after every scan" - which then means you have to periodically empty your trash manually to avoid all the little red trash symbols on intentionally deleted media, and the scary red "unavailable" buttons on upgraded files.
dumpsterr validates filesystem state before allowing Plex to empty trash:
- Checks directory accessibility
- Verifies minimum file counts
- Confirms file count thresholds are within an acceptable range:
if (files on disk / media in library) > minimum threshold in config - Only empties trash when all validations pass
- Plex Media Server with API access
- Docker (or Python 3.12+)
- Read access to media directories
Create data/config.yml:
libraries:
- name: Movies # Plex library name
path: /media/movies/ # Container path to media
min_files: 100 # Minimum files required
min_threshold: 90 # Minimum percentage of expected files
- name: TV Shows
path:
- /media/shows/
- /media/more-shows/
min_files: 50
min_threshold: 90
settings:
log_level: INFO # DEBUG, INFO, WARNING, ERROR, CRITICALConfiguration validation:
- Schema: src/public/config.schema.yml
- Validated on startup using jsonschema
Required:
PLEX_URL- Plex server URL (e.g.,http://192.168.1.100:32400)PLEX_TOKEN- Get your token
Optional:
TZ- Timezone (e.g.,America/New_York)
services:
dumpsterr:
image: neonvariant/dumpsterr:latest
container_name: dumpsterr
volumes:
- ./config.yml:/app/data/config.yml:ro
- /path/to/movies:/media/movies:ro
- /path/to/shows:/media/shows:ro
environment:
- PLEX_URL=${PLEX_URL}
- PLEX_TOKEN=${PLEX_TOKEN}
- TZ=${TZ}
restart: unless-stopped.env
PLEX_URL=http://<IP>:<PORT>
PLEX_TOKEN=PLEX-TOKEN-HERE
TZ=Time/ZoneRun:
docker compose up -ddocker run -d \
--name dumpsterr \
-v ./config.yml:/app/data/config.yml:ro \
-v /path/to/movies:/media/movies:ro \
-v /path/to/shows:/media/shows:ro \
-e PLEX_URL=http://192.168.1.100:32400 \
-e PLEX_TOKEN=your_token_here \
-e TZ=America/New_York \
--restart unless-stopped \
neonvariant/dumpsterr:latestgit clone https://github.com/chase-roohms/dumpsterr.git
cd dumpsterr
docker build -t dumpsterr .Runs hourly via supercronic (see src/crontab). Also executes on container startup.
To modify schedule, edit src/crontab and rebuild:
# Current: hourly
0 * * * * cd /app && /usr/local/bin/python src/main.py
# Example: every 6 hours
0 */6 * * * cd /app && /usr/local/bin/python src/main.py- Directory accessibility check
- Minimum file count verification
- Plex library size comparison
- Threshold percentage validation (current files / expected files > minimum threshold)
- Trash emptying (only if all checks pass)
Validation failure exits without emptying trash.
View logs:
docker logs dumpsterr
docker logs -f dumpsterr # Follow modeLog levels: DEBUG, INFO (default), WARNING, ERROR, CRITICAL
Error: IsADirectoryError: [Errno 21] Is a directory: 'data/config.yml'
Cause: The config file doesn't exist on your host system. When Docker tries to mount a non-existent file, it creates a directory instead.
Solution:
- Ensure the config file exists on your host at the path specified in your
docker-compose.yml - If using the quickstart, the config file should be in the same directory as your
docker-compose.yml - Recreate the container to remount the volume correctly:
docker compose down docker compose up -d
Example: If your docker-compose.yml has:
volumes:
- ./config.yml:/app/data/config.yml:roThen config.yml must exist in the same directory as docker-compose.yml before running docker compose up.
Check that:
PLEX_URLis accessible from the containerPLEX_TOKENis valid- Media paths in
config.ymlmatch the container paths (not host paths)
Disable "Empty trash automatically after every scan" in:
- Settings > Library
This lets dumpsterr control trash emptying on its schedule.
src/
├── main.py # Validation and orchestration
├── config/ # Configuration loading and validation
├── filesystem/ # Directory and file count checks
├── plex_client/ # Plex API interaction
└── public/ # JSON schema for config validation
- PyYAML
- jsonschema
- requests
See LICENSE file.