Stack gotchas
Use when hitting a known failure in my stack — release-please rate-limit or auto-merge loop, GitHub Pages env branch-policy, Supabase egress/RLS/stale-client-blob, a Flipper FAP release/build/version-triad failure or a FAP whose UI won't refresh when launched from favourites/quick-buttons, or verifying mobile/responsive rendering in WSL — for a direct diagnose-and-recover recipe.From its SKILL.md
npx -y skills add Endika/eskills --skill stack-gotchasAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
12.5 KB, ~3.1k tokens by cl100k_base, as published. Nobody here has run it
stack-gotchas
Overview
Diagnose-and-recover recipes for failures I've actually hit. Each is symptom → what it really means → fix — not a tutorial. Match the symptom, apply the recipe.
release-please: "Resource not accessible by integration"
- Symptom: release-please fails at "Creating N releases…" despite correct token perms.
- Means: GitHub secondary rate-limit (abuse detection) on the
github-actions[bot]token, not a permissions bug. Tell-tale: a release succeeded seconds earlier;gh api rate_limitcore looks healthy. Usually triggered by a burst (dependabot opening ~12 PRs). - Fix: (1) create the missing release with your user token, full 40-char SHA:
gh release create vX.Y.Z --target <full-sha> --title vX.Y.Z --notes "<CHANGELOG section>" --latest. (2) Swap the PR labelautorelease: pending→autorelease: taggedvia REST (gh api), or it retries forever. (3) Let the bot cooldown clear (~minutes–1h) with no more content-creation calls. Code usually deployed anyway (Pages runs on push independently).
release-please: infinite auto-merge loop
- Symptom: the release PR never merges; the workflow re-dispatches itself every ~90s.
- Means: the bot's PR (made with
GITHUB_TOKEN) gets no CI run → the requiredverifycheck never appears → auto-merge can't complete; it lands only via a fragile fast-forward that breaks ifmainadvanced by hand in parallel. - Fix: create the tag/release yourself at
mainHEAD (gh release create vX.Y.Z --target <main-sha>) → no pending release → no re-dispatch → loop stops. Replicate the bump inpackage.json+.release-please-manifest.json+CHANGELOG.mdvia a normal user PR so CI runs. Don't hand-mergemainmid-release. Durable fix: give release-please a PAT (its PRs then trigger CI) and drop the unconditional self-redispatch.
release-please: "GitHub Actions is not permitted to create or approve pull requests" (new repo)
- Symptom: on a freshly created repo, the Release workflow's release-please step
fails almost immediately (~15s) with
release-please failed: GitHub Actions is not permitted to create or approve pull requests.The CI workflow is fine; only release PR creation fails. - Means: new repos default the repo Actions setting to
default_workflow_permissions=read+can_approve_pull_request_reviews=false. release-please must open its release PR, and the repo/org toggle overrides the workflow-levelpermissions: pull-requests: write— so the in-workflow grant is not enough on its own. - Fix: enable it once (Settings → Actions → General → "Allow GitHub Actions to create
and approve pull requests"), via API:
Do this right aftergh api -X PUT repos/<owner>/<repo>/actions/permissions/workflow \ -f default_workflow_permissions=write -F can_approve_pull_request_reviews=true gh run rerun <failed-release-run-id>gh repo createfor any new FAP / sister app — it's a one-time per-repo setting, not a code or token problem. (Distinct from the secondary rate-limit and auto-merge-loop failures above.)
GitHub Pages: deploy rejected with empty logs after master→main rename
- Symptom: the deploy job fails with no steps and empty logs.
- Means: rejected at the environment gate — the
github-pagesenv's deployment-branch-policy still lists only the old branch (master). - Fix:
Set the default branch before the first deploy; ensure Pagesgh api -X POST repos/<owner>/<repo>/environments/github-pages/deployment-branch-policies -f name=main gh api repos/<owner>/<repo>/environments/github-pages/deployment-branch-policies --jq '.branch_policies[]' gh api -X DELETE repos/<owner>/<repo>/environments/github-pages/deployment-branch-policies/<id>build_type=workflow.
Verify mobile/responsive rendering in WSL (no sudo)
- Symptom: you need to see/measure real mobile widths but there's no Linux browser;
Windows Edge headless clamps window width to ~500px (screenshots <450px render a wider
layout cropped — misleading), and puppeteer can't drive the Windows
.exefrom WSL (stdio pipe breaks; its CDP debug port is unreachable over NAT). - Means: you need a native Linux Chromium, but the one puppeteer downloads is missing
libnss3/libnspr4/libasound2and there's no passwordless sudo. - Fix (all without root):
Drive vianpx -y @puppeteer/browsers install chrome@stable # native linux chromium apt-get download libnss3 libnspr4 libasound2t64 # download .deb, no sudo for d in *.deb; do dpkg -x "$d" root; done # extract libs locally # run with: LD_LIBRARY_PATH=$PWD/root/usr/lib/x86_64-linux-gnu <chrome> …puppeteer-core(executablePath= that chrome;LD_LIBRARY_PATHin the env). ThensetViewport({ width, deviceScaleFactor: 2, isMobile: true })at any width, measurescrollWidth/getBoundingClientRect, bisect overflow by togglingdisplay:noneper child, and confirm a fix by injecting the style and re-measuring before editing. Keep the env until done — don't re-download the ~150MB browser mid-task. - Before re-debugging a "still broken" UI report: confirm the user isn't on a stale
deploy or cached PWA (check the live tag + that
autoUpdateactivated). Much of this class of confusion is version lag, not a bug.
Supabase: egress blown (not DB size)
- Symptom: Free-tier limit hit while DB size is tiny.
- Means: the binding limit is egress ≈
blob_size × updates × connected_clients. Usually an unbounded field in a JSON blob growing quadratically (history/trash snapshots). - Fix: cap growing fields hard; make history an audit-log (no full snapshots); broadcast
only
{version}over Realtime and version-gate full fetches; write-through the local cache. Seeeskills:perf-bar. Next lever: split the growing field into its own table.
Supabase: open-write RLS
- Symptom: anyone with the anon key can overwrite a row via PostgREST.
- Means: RLS is
SELECT true+INSERT/UPDATE true; client-side PIN/rate-limit give no server protection (the anon key ships in the client). - Fix: restrict direct writes; enforce ownership/PIN in an RPC with RLS. See
eskills:security-bar.
Supabase: stale-client blob wipe
- Symptom: a newly-added field (e.g. subgroups) silently disappears after another user edits.
- Means: whole-blob rewrite + Zod stripping unknown keys + a manual-update PWA → a stale
cached client (running old code) drops fields its schema doesn't know on its next write.
The optimistic
versioncheck doesn't protect (same-version-lineage overwrite). - Fix: stamp
_schemaVersionon every write + a Postgres BEFORE UPDATE trigger rejecting writes whose version < stored (→ HTTP 426 → "please update" prompt); flip the PWA toautoUpdate. Operational rule: bumpSCHEMA_VERSIONwhenever the snapshot shape changes, or the guard won't protect the new field.
Flipper FAP: release-please leaves application.fam un-bumped
- Symptom: one leg of the triad stays behind on release — e.g.
application.fam'sfap_version, ORinclude/version.h's constant — while the others bump → catalog/CI mismatch, and an in-app "version" string shows the stale number. - Means: the
genericupdater only replaces a version on a line that itself carries thex-release-please-versionmarker. The marker must be INLINE on the same line as the value —fap_version="x.y.z" # x-release-please-versionand#define APP_VERSION "x.y.z" // x-release-please-version. A marker on a separate line above the#define(or a missing/edited marker) makes the updater silently no-op that file. (Hit on flipper-tutu: version.h had the marker on its own line and stuck at 0.1.0 while fam/manifest advanced.) - Fix: put the marker inline on each version-bearing line; sync the lagging file to the
current version once by hand; keep the triad
application.fam↔include/version.h↔.release-please-manifest.jsonaligned. Seestacks/references/flipper/release-please.md.
Flipper FAP: catalog submission rejected on version/commit
- Symptom: the official catalog CI fails the entry.
- Means: the manifest
commit_shapoints at a later fix commit instead of the tagged release commit, or the entry version ≠fap_version. - Fix: point
commit_shaat the release commit; make the catalog version equalfap_version. (Catalog-update-flow memory +stacks→ flipper.)
Flipper FAP: host test won't compile (furi symbols)
- Symptom:
make testfails to compile with undefined furi references. - Means: a file under test (transitively) includes
furi— furi isn't available on the host gcc build; the layering leaked. - Fix: keep
domain/pure C and move the furi-touching code behind a plain-C signature inplatform/. Only testdomain/. Seestacks/references/flipper/architecture.md.
Flipper FAP: cppcheck flags entry points as unusedFunction
- Symptom:
make lintererrors onunusedFunctionformain.c/*_app.c/ port files. - Means: those functions are called by the firmware, not within the TU — a cppcheck false positive, not dead code.
- Fix: add a path-scoped
--suppress=unusedFunction:<path>(or inline// cppcheck-suppress), never disable the check globally. Seestacks/references/flipper/formatting.md.
Flipper FAP: blank/stale UI when launched from favourites or quick-buttons
- Symptom: the screen is blank or frozen (UI never refreshes) when the app is opened from a desktop favourite or a quick-press button shortcut — but it works fine when opened from the Apps menu. (Reported by catalog users on two of my apps.)
- Means: the app only calls
view_port_update()in reaction to input — the main loop blocks onfuri_message_queue_get(..., FuriWaitForever)and paints nothing until a key is pressed. The Apps menu masks it: the loader's background hourglass animation forces a GUI redraw, so the first frame appears. Favourites/quick-buttons skip that loader → nothing triggers the draw. The app was leaning on an external redraw ("a bug"), not driving its own. - Fix: force the redraw from the app itself. (1) Draw once immediately after
gui_add_view_port(...)withview_port_update(view_port). (2) Don't depend on input to paint: either give the queue a finite timeout (furi_message_queue_get(q, &e, 50)) and callview_port_update()every loop tick, or call it after every state change (including the initial state). Same fix for aViewDispatcher/SceneManagerapp: ensure the first scene transition happens before the loop blocks. Seestacks/references/flipper/architecture.md.
GDPR: open-RLS exposes personal data
- Symptom: any anon key holder can read/update/delete rows that contain names, email, or financial data (e.g. EventSplit's events blob).
- Means: open-write RLS (
SELECT/INSERT/UPDATE true) isn't just a security bug — it's a personal-data exposure / breach risk under GDPR (unauthorized access to identifiable people, including third parties who never consented). - Fix: restrict direct writes / enforce ownership in an RPC (the security fix →
eskills:security-bar); then in the privacy notice, only claim protections you actually have. Don't document "your data is protected" while RLS is open. Seeeskills:gdpr.
GDPR: undisclosed international transfer to an AI provider
- Symptom: the app sends user audio/text to OpenAI/Anthropic/Google/Azure, but the privacy notice (if any) doesn't mention it (mintza).
- Means: that's a processor + international transfer (US) with no disclosure and no transfer mechanism named — a GDPR gap, and possibly special-category data (voice).
- Fix: disclose every AI provider as a processor + name the transfer basis (SCCs/DPF) in
the notice; confirm no-training-on-API-data + retention; send the model the minimum
content, no needless identifiers. See
eskills:gdpr(AI-processor posture).
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most design frontend skills give in ~3.1k tokens
Counted across 1,169 of the 1,878 authors here whose files we hold, read 2026-08-07
- Use CSS variables for color consistencyin 72 of 1169, across 23 files
- Commit to one bold aesthetic direction before codingin 72 of 1169, across 27 files
- Match implementation complexity to the aesthetic visionin 70 of 1169, across 20 files
- Add atmospheric background effects and texturesin 57 of 1169, across 9 files
- Use unexpected spatial compositions and layoutsin 56 of 1169, across 8 files
- Implement real working codein 55 of 1169, across 7 files
- Vary themes and aesthetics across different designsin 48 of 1169, across 7 files
- Launch chromium in headless modein 47 of 1169, across 4 files
- Close the browser when donein 47 of 1169, across 4 files
- Run provided scripts with help flag firstin 47 of 1169, across 4 files
- Wait for network idle statein 47 of 1169, across 4 files
- Use descriptive selectors for elementsin 47 of 1169, across 4 files
Said here and by no other author read
- match the symptom and apply the given recipe
- create missing releases manually using a user token
- swap release-please labels via rest api
- enable actions pull request creation via api for new repos
- add new branch policies via api after branch renames
- run native linux chromium without root for mobile testing
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.