docs: archive v1.3 and v2.0 milestones with roadmap, requirements, and retrospective
All checks were successful
CI / ci (push) Successful in 1m7s
CI / e2e (push) Has been skipped
CI / deploy (push) Successful in 7s

This commit is contained in:
2026-04-08 23:10:50 +02:00
parent cc0bafe754
commit f564e8cb54
12 changed files with 803 additions and 345 deletions

View File

@@ -0,0 +1,45 @@
---
status: awaiting_human_verify
trigger: "Client-side error 'can't access property id, w[0] is undefined' occurs after login"
created: 2026-04-08T00:00:00Z
updated: 2026-04-08T00:00:00Z
---
## Current Focus
hypothesis: CONFIRMED — AddToThreadModal.tsx has an unguarded activeThreads[0].id in a useEffect dependency array, which throws when there are no active threads (new user after login)
test: Root cause confirmed by code reading
expecting: Fix by replacing activeThreads[0].id with activeThreads[0]?.id in the dependency array
next_action: Apply fix
## Symptoms
expected: After login, app loads normally and shows user's collection
actual: Error thrown client-side: "can't access property 'id', w[0] is undefined"
errors: "can't access property 'id', w[0] is undefined" — minified variable name, from production/built bundle
reproduction: Happens after logging in (OIDC via Logto)
started: Unclear when it started, user noticed it now
## Eliminated
- hypothesis: Bug is in auth hooks or route guards
evidence: useAuth.ts and __root.tsx are clean — auth handles null/undefined safely
timestamp: 2026-04-08T00:00:00Z
- hypothesis: Bug is in categories[0].id access in CreateThreadModal, ManualEntryForm, or AddToCollectionModal
evidence: All three guard with `categories && categories.length > 0` before accessing [0].id
timestamp: 2026-04-08T00:00:00Z
## Evidence
- timestamp: 2026-04-08T00:00:00Z
checked: AddToThreadModal.tsx lines 62-68
found: useEffect dependency array evaluates `activeThreads[0].id` unconditionally. When activeThreads is empty (new user after login with no threads), this throws TypeError.
implication: This is the root cause. The guard `activeThreads.length === 0` inside the effect body does NOT protect the dependency array itself — React evaluates the dep array on every render.
## Resolution
root_cause: In AddToThreadModal.tsx, the useEffect dependency array at lines 62-68 directly accesses `activeThreads[0].id` without optional chaining. When a user logs in with no active threads (empty array), React evaluates this expression during render and throws "can't access property 'id', w[0] is undefined".
fix: Replace `activeThreads[0].id` with `activeThreads[0]?.id` in the useEffect dependency array
verification: Fix applied — changed `activeThreads[0].id` to `activeThreads[0]?.id` in useEffect dependency array. This prevents the TypeError when activeThreads is empty.
files_changed: [src/client/components/AddToThreadModal.tsx]

View File

@@ -0,0 +1,70 @@
---
status: fixing
trigger: "GearBox deployed on Coolify throws Invalid session (HTTP 500) from @hono/oidc-auth middleware when accessing GET /login"
created: 2026-04-08T00:00:00Z
updated: 2026-04-08T00:01:00Z
---
## Current Focus
hypothesis: CONFIRMED — oidcAuthMiddleware swallows all errors (including OIDC discovery network failures) as "Invalid session". The actual error is most likely Logto OIDC discovery endpoint unreachable from the Docker container.
test: deployed OIDC startup check — check Coolify logs after next deploy for "[OIDC]" lines
expecting: logs will show either "Discovery endpoint reachable" or "Discovery endpoint unreachable" with the actual network error
next_action: await_human_verify — user deploys and checks Coolify logs
## Symptoms
expected: User visits /login, gets redirected to Logto for authentication, completes login, and returns with a valid session.
actual: GET /login immediately throws HTTP 500 "Invalid session" from @hono/oidc-auth middleware. The error originates at node_modules/@hono/oidc-auth/dist/index.js:330 — the OIDC session validation catches an error, deletes the cookie, and throws.
errors: |
Error thrown at node_modules/@hono/oidc-auth/dist/index.js:330 in the catch block.
The middleware catches ALL errors from OIDC session validation and throws HTTPException 500 "Invalid session".
reproduction: Visit the deployed GearBox instance's /login page
started: Was an existing issue locally, temporarily fixed (possibly via Logto config/DB changes), but broke again on deploy to Coolify
## Eliminated
- hypothesis: Missing/invalid OIDC env vars (OIDC_AUTH_SECRET too short, OIDC_ISSUER missing, etc.)
evidence: getOidcAuthEnv() throws with DIFFERENT messages for missing vars (not "Invalid session"). The error at line 330 only runs AFTER getOidcAuthEnv succeeds. .env.coolify-test shows 32-char secret (minimum OK).
timestamp: 2026-04-08
- hypothesis: Stale session cookie from wrong-secret JWT
evidence: If verify() fails (wrong secret), the inner try-catch at line 123-127 catches it and returns null — not throw. Only throws at line 129 if cookie decodes OK but rtkexp/ssnexp are undefined. This would require the same secret but different JWT structure.
timestamp: 2026-04-08
- hypothesis: Error is thrown from setOidcAuthEnv before try-catch
evidence: getOidcAuthEnv is called at line 293 OUTSIDE the try block. If it threw, the error message would be from setOidcAuthEnv ("Session secret is not provided", etc.), not "Invalid session".
timestamp: 2026-04-08
## Evidence
- timestamp: 2026-04-08
checked: @hono/oidc-auth/dist/index.js lines 292-330 (oidcAuthMiddleware)
found: The outer try-catch at line 298-330 wraps ALL of: getAuth(c), and the redirect-building code (generateAuthorizationRequestUrl → getAuthorizationServer → OIDC discovery fetch). Any error from any of these is caught and re-thrown as HTTPException(500, "Invalid session"). The original error is LOST.
implication: "Invalid session" is a misleading umbrella for any failure in the login flow.
- timestamp: 2026-04-08
checked: Error stack trace — lines 325-326 are setCookie("continue"...) and c.redirect(url), inside the if(getAuth===null) block
found: These lines are context in the error display, NOT where the error occurred. The throw is at line 330 (catch block). The fact that code is within the getAuth===null branch means getAuth returned null (no cookie or expired) and then generateAuthorizationRequestUrl was called — which calls getAuthorizationServer — which does OIDC discovery.
implication: The error occurred during OIDC discovery (network call to OIDC_ISSUER/.well-known/openid-configuration).
- timestamp: 2026-04-08
checked: src/server/index.ts app.onError handler
found: Custom onError does NOT handle HTTPException specially — it bypasses getResponse() and returns generic JSON. Hono's default handler uses getResponse() for HTTPException. Both log the error, but the logged HTTPException doesn't carry the original network error (the catch in oidcAuthMiddleware doesn't attach original cause).
implication: Server logs show "Invalid session" HTTPException but not the original TypeError (network error). This made diagnosis harder.
- timestamp: 2026-04-08
checked: OIDC env vars in .env.coolify-test
found: OIDC_ISSUER=https://auth.gearbox-test.jeanlucmakiola.de/oidc, OIDC_AUTH_SECRET=8515017c9c54186230b6d5210b08a94b (32 chars), OIDC_REDIRECT_URI=https://gearbox-test.jeanlucmakiola.de/callback. All look structurally valid.
implication: The issue is NOT invalid env var values — it's runtime failure when using them.
## Resolution
root_cause: oidcAuthMiddleware swallows all errors as "Invalid session" — the actual error is almost certainly the OIDC discovery fetch failing because Logto (https://auth.gearbox-test.jeanlucmakiola.de) is either not running, not accessible from the Docker container, or the OIDC_ISSUER URL is wrong in Coolify's environment.
fix: |
1. Added OIDC startup connectivity check in src/server/index.ts that fetches OIDC_ISSUER/.well-known/openid-configuration at startup and logs the real error if it fails.
2. Fixed app.onError to properly return HTTPException.getResponse() so the correct status/message is preserved.
3. To fully fix: deploy, check Coolify logs for "[OIDC]" lines, and fix whatever the actual cause is (restart Logto, fix Coolify network, correct OIDC_ISSUER URL).
verification:
files_changed:
- src/server/index.ts