Pinchlist continually restarts, while TomAi says is is not and running, its logging in updates contantly? The app works fine if you bookmark the page at first launch, but you will not be able to access after set up unless you get lucky to launch at the right moment in the middle of the restart.
18 replies
tomspark wrote:
That's the answer I was hoping for — those logs are clean. Pinchflat is working perfectly: serving the page, running its jobs, no errors anywhere. So it's exactly what I suspected: the app is fine, but SparkBox's health check is wrongly flagging it as sick, and that false 'unhealthy' is what triggers the constant restarts (which is why you can only catch it between them). That's our bug, not yours, and I'm fixing it. One last quick command so I patch the right thing — it shows exactly why the health check is failing: sudo docker inspect --format '{{json .State.Health}}' sb-pinchflat Paste that and I'll ship the fix. Really sorry it's been this annoying — you did the hard part by getting me the logs.
tomspark wrote:
That's the marathon finished — so glad it's all sorted! You did the hard part getting me those exact logs along the way, which is what pinned the health-check bug (now fixed for everyone in 1.6.285) and got the media stack back up. Enjoy Pinchflat doing its thing, and shout anytime.
tomspark wrote:
Sounds frustrating — but you haven't broken anything. The "Pinchlist continually restarts" behavior, combined with TomAi showing it as running, usually means the container is resetting before it's fully ready. Can you grab the logs so we can see what's happening? Run sudo sparkbox logs pinchlist in a terminal and paste the last 20-30 lines here — that'll tell us exactly where it's getting stuck.
Wildwood32 wrote:
Wildwood@WildwoodNas:~$ sudo sparkbox logs pinchlist [sudo] password for Wildwood: Error response from daemon: No such container: pinchlist Wildwood@WildwoodNas:~$ sudo -i root@WildwoodNas:~ sudo sparkbox logs pinchlist Error response from daemon: No such container: pinchlist root@WildwoodNas:~
tomspark wrote:
That 'No such container: pinchlist' error means Pinchlist isn't running right now — it looks like it's crashing shortly after it starts. That's not something you did wrong, and we should be able to figure out what's going on. Can you run sudo sparkbox doctor and paste the output here? That'll show us exactly what state Pinchlist and the rest of your apps are in. Also let us know what the Pinchlist tile shows in your SparkBox dashboard — running, stopped, or something else.
Wildwood32 wrote:
SparkBox v1.6.245 - Self-Hosted Privacy Stack Created by Tom Spark | youtube.com/@TomSparkReviews Environment: NAS (generic) SparkBox Doctor Running diagnostics... [Install location] [OK] SparkBox is installed at: /volume2/sparkbox [OK] Settings file (.env): /volume2/sparkbox/.env [OK] Media library folder (MEDIAROOT): /home/Wildwood/Media [Docker] [OK] Docker daemon is accessible [OK] Docker version: Docker version 26.1.0, build 9714adc [OK] Docker Compose: 2.26.1 [Docker Socket] [OK] Docker socket exists at /var/run/docker.sock [OK] Docker socket is readable [User IDs] [INFO] Current user: root (UID=0, GID=0) [OK] PUID=1000 (containers run as UID 1000) [OK] PGID=1000 (containers run as GID 1000) [Container Egress] [OK] Containers can reach webhook.tomsparkbox.com (license server) [Port Conflicts] [WARN] Port 53: in use by non-Docker process LISTEN 0 32 127.0.0.1:53 0.0.0.0: users:(("dnsmasq",pid=1495,fd=5)) [WARN] Port 80: in use by non-Docker process LISTEN 0 511 0.0.0.0:80 0.0.0.0: users:(("nginx",pid=2340,fd=6),("nginx",pid=2339,fd=6),("nginx",pid=2338,fd=6),("nginx",pid=2337,fd=6),("nginx",pid=2336,fd=6),("nginx",pid=2335,fd=6),("nginx",pid=1597,fd=6)) [WARN] Port 443: in use by non-Docker process LISTEN 0 511 0.0.0.0:443 0.0.0.0: users:(("nginx",pid=2340,fd=8),("nginx",pid=2339,fd=8),("nginx",pid=2338,fd=8),("nginx",pid=2337,fd=8),("nginx",pid=2336,fd=8),("nginx",pid=2335,fd=8),("nginx",pid=1597,fd=8)) [OK] Port 8080: in use (Docker -- likely SparkBox) [OK] Port 8443: in use (Docker -- likely SparkBox) [OK] Port 9000: in use (Docker -- likely SparkBox) [OK] Port 9092: available [Portainer Auth] [OK] Portainer admin login verified (HTTP 200) [VPN Tunnel] [OK] Gluetun tunnel is healthy [Hardware Transcoding] [OK] /dev/dri exists -- GPU devices detected total 0 drwxr-xr-x 3 root root 100 Jun 10 18:24 . drwxr-xr-x 20 root root 7740 Jun 11 06:54 .. drwxr-xr-x 2 root root 80 Jun 10 18:24 by-path crw-rw---- 1 root video 226, 0 Jun 10 18:24 card0 crw-rw---- 1 root render 226, 128 Jun 10 18:24 renderD128 [OK] Intel Quick Sync / GPU render device available (renderD128) [OK] Render device is accessible by current user [Media Storage] [OK] MEDIAROOT=/home/Wildwood/Media exists [OK] MEDIAROOT is writable [OK] Your apps (user id 1000) can read your media library [INFO] Free space at MEDIAROOT: 13224GB [System Resources] [INFO] Total RAM: 7712MB [INFO] Available RAM: 4004MB [OK] RAM looks sufficient for 5 enabled modules [INFO] Free disk at SBROOT: 884GB [NAS-Specific] [INFO] NAS type: generic [INFO] Install directory: /volume2/sparkbox [OK] Install directory is on a data volume [Container Health] [OK] All SparkBox containers are running [Tailscale Reachability] [OK] Dashboard reachable on the LAN IP (192.168.0.30:8443) — no Tailscale route shadow ============================================ 3 issue(s) found. Review warnings above and fix as needed. ============================================ Wildwood@WildwoodNas:~$
tomspark wrote:
Looks like a healthy setup overall — Docker is working, drive space is fine, and everything core checks out. The port 80 and 443 warnings are just your NAS's built-in web server taking those spots, which is totally normal. The tricky part here is Pinchlist is crashing so fast there's no container left to read logs from. To catch what's actually going wrong, open the SparkBox dashboard, click Pinchlist to restart it, then run this in a terminal right away: sudo docker ps -a | grep -i pinch Paste what you see and we'll be able to pull the exit reason from there.
Wildwood32 wrote:
Wildwood@WildwoodNas:~$ sudo docker ps -a | grep -i pinch [sudo] password for Wildwood: e4d5882feefd ghcr.io/kieraneglin/pinchflat:v2025.6.6 "/app/bin/dockersta…" 4 hours ago Up About a minute (unhealthy) 0.0.0.0:8945-8945/tcp, :::8945-8945/tcp sb-pinchflat
tomspark wrote:
Found it — there was a Pinchflat restart-loop bug we fixed in version 1.6.246, and your doctor shows you're on 1.6.245, so you're just one version behind it. Run sudo sparkbox update, then give Pinchflat a couple of minutes to settle. The '(unhealthy)' you saw should clear once it's on the fixed version and stops restarting. If it's still flapping after the update, let me know and we'll dig in further — but this should sort it.
Wildwood32 wrote:
Yeah, that was not the solution still having issues, Going to uninstall and try on another machoine. If i develop the same issue then I will know its the app and not sparkbox.
tomspark wrote:
Totally fair to test it on another machine — that's a smart way to isolate it. But before you tear it down, one command will tell us in two minutes whether it's Pinchflat itself or just SparkBox's health check being wrong. Now that it stays up about a minute, it finally leaves logs behind — grab them: sudo docker logs --tail 40 sb-pinchflat Paste that here. If Pinchflat is actually erroring (a database or permission line), we'll see it plainly. If those logs look totally normal but it's STILL flagged unhealthy, then the problem is SparkBox's health check falsely marking a working app as sick — which is on us, and I can patch it. Either way the logs settle it. Sorry this one's been stubborn.
Wildwood32 wrote:
t2026-06-19T05:49:31.331344253Z SELECT s0."id", s0."onboarding", s0."proenabled", s0."ytdlpversion", s0."appriseversion", s0."appriseserver", s0."youtubeapikey", s0."routetoken", s0."extractorsleepintervalseconds", s0."downloadthroughputlimit", s0."restrictfilenames", s0."videocodecpreference", s0."audiocodecpreference" FROM "settings" AS s0 LIMIT 1 [] -2026-06-19T05:49:31.331824715Z 2026-06-19 05:49:31.331 [info] | {"args":{},"id":4089,"meta":{},"state":"success","maxattempts":20,"queue":"localdata","worker":"Pinchflat.YtDlp.UpdateWorker","source":"oban","duration":1412069,"event":"job:stop","attempt":1,"queuetime":917837,"tags":["localdata"]} �2026-06-19T05:49:59.911046940Z 2026-06-19 05:49:59.910 [info] | {"source":"oban","duration":2575,"event":"plugin:stop","plugin":"Oban.Plugins.Pruner","prunedcount":0} �2026-06-19T05:50:00.909081905Z 2026-06-19 05:50:00.908 [info] | {"source":"oban","duration":566,"event":"plugin:stop","jobs":[],"plugin":"Oban.Plugins.Cron"} �2026-06-19T05:50:29.914670478Z 2026-06-19 05:50:29.914 [info] | {"source":"oban","duration":3183,"event":"plugin:stop","plugin":"Oban.Plugins.Pruner","prunedcount":0} �2026-06-19T05:50:59.918646170Z 2026-06-19 05:50:59.918 [info] | {"source":"oban","duration":3006,"event":"plugin:stop","plugin":"Oban.Plugins.Pruner","prunedcount":0} �2026-06-19T05:51:00.910093355Z 2026-06-19 05:51:00.909 [info] | {"source":"oban","duration":468,"event":"plugin:stop","jobs":[],"plugin":"Oban.Plugins.Cron"} f2026-06-19T05:51:07.620661410Z 2026-06-19 05:51:07.619 requestid=GLpljwsTQvTLgeMAABGh [info] | GET / �2026-06-19T05:51:07.620914052Z 2026-06-19 05:51:07.619 requestid=GLpljwsTQvTLgeMAABGh [debug] | Processing with PinchflatWeb.Pages.PageController.home/2 12026-06-19T05:51:07.620969885Z Parameters: %{} 72026-06-19T05:51:07.620978366Z Pipelines: [:browser] �2026-06-19T05:51:07.623344008Z 2026-06-19 05:51:07.621 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="settings" db=0.9ms queue=0.2ms idle=1395.8ms t2026-06-19T05:51:07.623392306Z SELECT s0."id", s0."onboarding", s0."proenabled", s0."ytdlpversion", s0."appriseversion", s0."appriseserver", s0."youtubeapikey", s0."routetoken", s0."extractorsleepintervalseconds", s0."downloadthroughputlimit", s0."restrictfilenames", s0."videocodecpreference", s0."audiocodecpreference" FROM "settings" AS s0 LIMIT 1 [] �2026-06-19T05:51:07.627919253Z 2026-06-19 05:51:07.626 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="mediaprofiles" db=3.6ms queue=0.8ms idle=496.8ms T2026-06-19T05:51:07.627967153Z SELECT count(m0."id") FROM "mediaprofiles" AS m0 [] �2026-06-19T05:51:07.630514018Z 2026-06-19 05:51:07.629 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="sources" db=0.6ms queue=1.6ms idle=409.4ms M2026-06-19T05:51:07.630674336Z SELECT count(s0."id") FROM "sources" AS s0 [] �2026-06-19T05:51:07.637716476Z 2026-06-19 05:51:07.636 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="mediaitems" db=6.3ms queue=0.4ms idle=403.5ms �2026-06-19T05:51:07.637763783Z SELECT sum(m0."mediasizebytes") FROM "mediaitems" AS m0 WHERE (NOT (m0."mediafilepath" IS NULL)) [] �2026-06-19T05:51:07.639676565Z 2026-06-19 05:51:07.638 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="mediaitems" db=1.0ms queue=0.3ms idle=410.6ms {2026-06-19T05:51:07.639762773Z SELECT count(m0."id") FROM "mediaitems" AS m0 WHERE (NOT (m0."mediafilepath" IS NULL)) [] �2026-06-19T05:51:07.640474126Z 2026-06-19 05:51:07.639 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="settings" db=0.5ms queue=0.1ms idle=17.7ms t2026-06-19T05:51:07.640516085Z SELECT s0."id", s0."onboarding", s0."proenabled", s0."ytdlpversion", s0."appriseversion", s0."appriseserver", s0."youtubeapikey", s0."routetoken", s0."extractorsleepintervalseconds", s0."downloadthroughputlimit", s0."restrictfilenames", s0."videocodecpreference", s0."audiocodecpreference" FROM "settings" AS s0 LIMIT 1 [] �2026-06-19T05:51:07.641700379Z 2026-06-19 05:51:07.640 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="settings" db=0.3ms idle=14.1ms t2026-06-19T05:51:07.641723936Z SELECT s0."id", s0."onboarding", s0."proenabled", s0."ytdlpversion", s0."appriseversion", s0."appriseserver", s0."youtubeapikey", s0."routetoken", s0."extractorsleepintervalseconds", s0."downloadthroughputlimit", s0."restrictfilenames", s0."videocodecpreference", s0."audiocodecpreference" FROM "settings" AS s0 LIMIT 1 [] �2026-06-19T05:51:07.644127179Z 2026-06-19 05:51:07.642 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="settings" db=0.4ms idle=12.2ms t2026-06-19T05:51:07.644179511Z SELECT s0."id", s0."onboarding", s0."proenabled", s0."ytdlpversion", s0."appriseversion", s0."appriseserver", s0."youtubeapikey", s0."routetoken", s0."extractorsleepintervalseconds", s0."downloadthroughputlimit", s0."restrictfilenames", s0."videocodecpreference", s0."audiocodecpreference" FROM "settings" AS s0 LIMIT 1 [] �2026-06-19T05:51:07.645032819Z 2026-06-19 05:51:07.644 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="tasks" db=0.5ms idle=7.1ms q2026-06-19T05:51:07.645057900Z SELECT t0."id", t0."jobid", t0."sourceid", t0."mediaitemid", t0."insertedat", t0."updatedat", o1."id", o1."state", o1."queue", o1."worker", o1."args", o1."meta", o1."tags", o1."errors", o1."attempt", o1."attemptedby", o1."maxattempts", o1."priority", o1."attemptedat", o1."cancelledat", o1."completedat", o1."discardedat", o1."insertedat", o1."scheduledat" FROM "tasks" AS t0 LEFT OUTER JOIN "obanjobs" AS o1 ON o1."id" = t0."jobid" WHERE (o1."state" IN (?)) AND (? IN (SELECT value FROM JSONEACH(o1."tags"))) ORDER BY o1."attemptedat" DESC ["executing", "showindashboard"] �2026-06-19T05:51:07.650289959Z 2026-06-19 05:51:07.649 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="mediaitems" db=0.8ms queue=0.4ms idle=9.2ms �2026-06-19T05:51:07.650340732Z SELECT count(m0."id") FROM "mediaitems" AS m0 INNER JOIN "sources" AS s1 ON s1."id" = m0."sourceid" INNER JOIN "mediaprofiles" AS m2 ON m2."id" = s1."mediaprofileid" WHERE (NOT (m0."mediafilepath" IS NULL)) [] �2026-06-19T05:51:07.652902694Z 2026-06-19 05:51:07.652 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="mediaitems" db=1.5ms queue=0.6ms idle=9.8ms E2026-06-19T05:51:07.652936943Z SELECT m0."id", m0."uuid", m0."title", m0."mediaid", m0."description", m0."originalurl", m0."livestream", m0."shortformcontent", m0."mediadownloadedat", m0."mediaredownloadedat", m0."uploadedat", m0."uploaddateindex", m0."durationseconds", m0."playlistindex", m0."predictedmediafilepath", m0."mediafilepath", m0."mediasizebytes", m0."thumbnailfilepath", m0."metadatafilepath", m0."nfofilepath", m0."subtitlefilepaths", m0."lasterror", m0."preventdownload", m0."preventculling", m0."culledat", m0."sourceid", m0."insertedat", m0."updatedat" FROM "mediaitems" AS m0 INNER JOIN "sources" AS s1 ON s1."id" = m0."sourceid" INNER JOIN "mediaprofiles" AS m2 ON m2."id" = s1."mediaprofileid" WHERE (NOT (m0."mediafilepath" IS NULL)) ORDER BY m0."id" DESC LIMIT ? OFFSET ? [5, 0] �2026-06-19T05:51:07.655613673Z 2026-06-19 05:51:07.653 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="sources" db=0.6ms queue=0.3ms idle=12.0ms �2026-06-19T05:51:07.655650688Z SELECT s0."id", s0."enabled", s0."uuid", s0."customname", s0."description", s0."collectionname", s0."collectionid", s0."collectiontype", s0."indexfrequencyminutes", s0."fastindex", s0."cookiebehaviour", s0."downloadmedia", s0."lastindexedat", s0."downloadcutoffdate", s0."retentionperioddays", s0."originalurl", s0."titlefilterregex", s0."outputpathtemplateoverride", s0."mindurationseconds", s0."maxdurationseconds", s0."seriesdirectory", s0."nfofilepath", s0."posterfilepath", s0."fanartfilepath", s0."bannerfilepath", s0."markedfordeletionat", s0."mediaprofileid", s0."insertedat", s0."updatedat", s0."id" FROM "sources" AS s0 WHERE (s0."id" = ?) [2] �2026-06-19T05:51:07.657917728Z 2026-06-19 05:51:07.656 requestid=GLpljwsTQvTLgeMAABGh [debug] | QUERY OK source="mediaitems" db=0.8ms queue=0.5ms idle=13.4ms �2026-06-19T05:51:07.657954665Z SELECT count(m0."id") FROM "mediaitems" AS m0 INNER JOIN "sources" AS s1 ON s1."id" = m0."sourceid" INNER JOIN "mediaprofiles" AS m2 ON m2."id" = s1."mediaprofileid" WHERE (((((NOT (NOT (m0."mediafilepath" IS NULL)) AND NOT (m0."preventdownload" = 1)) AND ((s1."downloadcutoffdate" IS NULL) OR date(m0."uploadedat") = s1."downloadcutoffdate")) AND CASE i2026-06-19T05:51:07.657961728Z WHEN shortsbehaviour = 'only' AND livestreambehaviour = 'only' THEN T2026-06-19T05:51:07.657964325Z livestream = true OR shortformcontent = true G2026-06-19T05:51:07.657966593Z WHEN shortsbehaviour = 'only' THEN ?2026-06-19T05:51:07.657968799Z shortformcontent = true K2026-06-19T05:51:07.657970939Z WHEN livestreambehaviour = 'only' THEN 72026-06-19T05:51:07.657973427Z livestream = true o2026-06-19T05:51:07.657975717Z WHEN shortsbehaviour = 'exclude' AND livestreambehaviour = 'exclude' THEN W2026-06-19T05:51:07.657979462Z shortformcontent = false AND livestream = false J2026-06-19T05:51:07.657983975Z WHEN shortsbehaviour = 'exclude' THEN @2026-06-19T05:51:07.657988393Z shortformcontent = false N2026-06-19T05:51:07.657993289Z WHEN livestreambehaviour = 'exclude' THEN 82026-06-19T05:51:07.657997279Z livestream = false (2026-06-19T05:51:07.658000151Z ELSE 2026-06-19T05:51:07.658003017Z true %2026-06-19T05:51:07.658005733Z END :2026-06-19T05:51:07.658008878Z ) AND ((s1."titlefilterregex" IS NULL) OR regexplike(m0."title", s1."titlefilterregex"))) AND (((s1."mindurationseconds" IS NULL) OR durationseconds = s1."mindurationseconds") AND ((s1."maxdurationseconds" IS NULL) OR durationseconds <= s1."maxd
Wildwood32 wrote:
{"Status":"unhealthy","FailingStreak":3,"Log":[{"Start":"2026-06-19T12:08:27.53572811-06:00","End":"2026-06-19T12:08:27.612516872-06:00","ExitCode":1,"Output":"/bin/sh: 1: wget: not found\n/bin/sh: 1: wget: not found\n"},{"Start":"2026-06-19T12:08:57.613995882-06:00","End":"2026-06-19T12:08:57.697456824-06:00","ExitCode":1,"Output":"/bin/sh: 1: wget: not found\n/bin/sh: 1: wget: not found\n"},{"Start":"2026-06-19T12:09:57.497081476-06:00","End":"2026-06-19T12:09:57.566613794-06:00","ExitCode":1,"Output":"/bin/sh: 1: wget: not found\n/bin/sh: 1: wget: not found\n"},{"Start":"2026-06-19T12:10:27.568165083-06:00","End":"2026-06-19T12:10:27.638046507-06:00","ExitCode":1,"Output":"/bin/sh: 1: wget: not found\n/bin/sh: 1: wget: not found\n"},{"Start":"2026-06-19T12:10:57.638458999-06:00","End":"2026-06-19T12:10:57.71571397-06:00","ExitCode":1,"Output":"/bin/sh: 1: wget: not found\n/bin/sh: 1: wget: not found\n"}]}
tomspark wrote:
That's the smoking gun — thank you. 'wget: not found' means our health check is calling a tool that isn't actually inside the Pinchflat app, so it fails every single time, and the system keeps restarting a perfectly healthy app on a loop. 100% on us, not you. I'm fixing the health check now and pushing it out in an update shortly — once you run sudo sparkbox update, the restart loop stops and Pinchflat just sits there healthy and reachable like it should. I'll post right here the moment it's live. Genuinely appreciate you sticking with this and getting me the exact logs — that's what nailed it.
tomspark wrote:
Quick follow-up — even better news: that health-check fix actually already went out in a recent update, so you don't have to wait on me at all. Just run sudo sparkbox update now, give Pinchflat a minute to come up, and you'll be on the fixed version where it stops restarting (the health check now uses a tool that's actually in the app). If it somehow still loops after updating, shout and I'll dig straight back in — but this should be the end of it. Thanks again for the great logs!
Wildwood32 wrote:
So after running the script, now my media server apps will not restart. Frustrating!!!
tomspark wrote:
Ah, sorry — I know that's annoying after all this. Good news though: your apps aren't broken, they're just stopped. An update stops everything to swap in the new versions, and sometimes the media stack doesn't auto-start back up cleanly afterward. One command brings it all back: sudo sparkbox up Give it a minute or two — it recreates the whole stack. If anything in the output goes red or it stops on an error, paste me the last 15 or so lines and I'll tell you exactly what to do next. Your data and config are all safe — this is just getting them running again.
Wildwood32 wrote:
I found that the media stack needed an update too, working now.