Skip to content

fix(ci): cross-platform path-separator + secret defaults (wave-12.6.3… #577

fix(ci): cross-platform path-separator + secret defaults (wave-12.6.3…

fix(ci): cross-platform path-separator + secret defaults (wave-12.6.3… #577

Triggered via push May 24, 2026 22:24
Status Failure
Total duration 3m 44s
Artifacts

ci.yml

on: push
playwright-smoke
playwright-smoke
playwright-a11y
playwright-a11y
Fit to window
Zoom out
Zoom in

Annotations

12 errors and 2 warnings
backend
Process completed with exit code 1.
test/messaging.socket.deep.test.js > messaging.socket.deep — live handler behavior > typing:start is silently dropped when caller is NOT a participant: backend/test/messaging.socket.deep.test.js#L92
Error: Cannot find package 'socket.io-client' imported from /home/runner/work/studyhub/studyhub/backend/test/messaging.socket.deep.test.js ❯ connectClient test/messaging.socket.deep.test.js:92:28 ❯ test/messaging.socket.deep.test.js:230:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { code: 'ERR_MODULE_NOT_FOUND' }
test/messaging.socket.deep.test.js > messaging.socket.deep — live handler behavior > typing:start broadcasts when caller IS a participant: backend/test/messaging.socket.deep.test.js#L92
Error: Cannot find package 'socket.io-client' imported from /home/runner/work/studyhub/studyhub/backend/test/messaging.socket.deep.test.js ❯ connectClient test/messaging.socket.deep.test.js:92:28 ❯ test/messaging.socket.deep.test.js:214:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { code: 'ERR_MODULE_NOT_FOUND' }
test/messaging.socket.deep.test.js > messaging.socket.deep — live handler behavior > typing:start with no conversationId is silently dropped (no broadcast): backend/test/messaging.socket.deep.test.js#L92
Error: Cannot find package 'socket.io-client' imported from /home/runner/work/studyhub/studyhub/backend/test/messaging.socket.deep.test.js ❯ connectClient test/messaging.socket.deep.test.js:92:28 ❯ test/messaging.socket.deep.test.js:203:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { code: 'ERR_MODULE_NOT_FOUND' }
frontend
Process completed with exit code 1.
src/pages/auth/useRegisterFlow.test.jsx > useRegisterFlow — Google needs_role branching > stashes tempToken in sessionStorage and routes to /signup/role: frontend/studyhub-app/src/pages/auth/useRegisterFlow.test.jsx#L67
AssertionError: expected null to match object { tempToken: 'tok-abc', …(4) } - Expected: { "avatarUrl": "https://example.com/a.png", "email": "x@y.test", "name": "X Y", "referralCode": "REF42", "tempToken": "tok-abc", } + Received: null ❯ src/pages/auth/useRegisterFlow.test.jsx:67:20
src/pages/auth/RolePickerPage.test.jsx > RolePickerPage > surfaces backend errors and does not navigate: frontend/studyhub-app/src/pages/auth/RolePickerPage.test.jsx#L130
TestingLibraryElementError: Unable to find role="alert" Ignored nodes: comments, script, style <body> <div> <main style="max-width: 480px; margin: 56px auto; padding: 0px 20px; display: grid; gap: 20px;" > <header style="display: grid; gap: 8px;" > <h1 style="margin: 0px; font-size: 24px; font-weight: 800; color: var(--sh-heading);" > One more step </h1> <p style="margin: 0px; color: var(--sh-subtext); font-size: 14px;" > Tell us how you plan to use StudyHub. You can change this later in Settings. </p> <p style="margin: 0px; color: var(--sh-muted); font-size: 13px;" > Continuing as <strong> new@example.com </strong> </p> </header> <div style="display: grid; gap: 6px;" > <label for="rolepicker-username" style="font-size: 13px; font-weight: 700; color: var(--sh-heading);" > Choose your username </label> <input autocomplete="username" id="rolepicker-username" maxlength="20" placeholder="3-20 chars, letters/numbers/_" style="width: 100%; box-sizing: border-box; padding: 11px 12px; border-radius: 10px; border: 1px solid var(--sh-input-border); background: var(--sh-input-bg, var(--sh-surface)); color: var(--sh-input-text, var(--sh-text)); font-size: 14px; font-family: inherit;" type="text" value="new" /> <span style="font-size: 12px; color: var(--sh-danger-text);" > Already taken. </span> </div> <div style="display: grid; gap: 8px;" > <label style="display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--sh-text);" > <input checked="" type="checkbox" /> Set a password (recommended — used when deleting your account or changing email) </label> <div style="display: grid; gap: 8px;" > <input autocomplete="new-password" placeholder="Password (8+ chars, 1 capital, 1 number)" style="width: 100%; box-sizing: border-box; padding: 11px 12px; border-radius: 10px; border: 1px solid var(--sh-input-border); background: var(--sh-input-bg, var(--sh-surface)); color: var(--sh-input-text, var(--sh-text)); font-size: 14px; font-family: inherit;" type="password" value="" /> <input autocomplete="new-password" placeholder="Confirm password" style="width: 100%; box-sizing: border-box; padding: 11px 12px; border-radius: 10px; border: 1px solid var(--sh-input-border); background: var(--sh-input-bg, var(--sh-surface)); color: var(--sh-input-text, var(--sh-text)); font-size: 14px; font-family: inherit;" type="password" value="" /> </div> </div> <fieldset style="border: 0px; padding: 0px; margin: 0px; display: grid; gap: 10px;" > <legend style="font-size: 13px; font-weight: 700; color: var(--sh-heading); margin-bottom: 4px;" > I am a… </legend> <label style="display: flex; align-items: center; gap: 12px; padding: 14px 16px; border: 1px solid var(--sh-brand); background: var(--sh-brand-soft); border-radius: 12px; cursor: pointer; min-height: 44px;" > <input name="accountType" style="accent-color: var(--sh-brand);" type="radio" value="student" /> <span style="font-weight: 600; color: var(--sh-heading);" > Student </span> </label> <label style="display: flex; align-items: center; gap: 12px; padding: 14px 16px; border: 1px solid var(--sh-border); background: var(--sh-surface); border-radius
src/pages/auth/RolePickerPage.test.jsx > RolePickerPage > posts tempToken + accountType to /google/complete and navigates to nextRoute: frontend/studyhub-app/src/pages/auth/RolePickerPage.test.jsx#L98
AssertionError: expected "vi.fn()" to be called with arguments: [ …(2) ] Received: 1st vi.fn() call: [ - "http://test.local/api/auth/google/complete", - ObjectContaining { + "http://test.local/api/auth/check-username?username=new", + { "credentials": "include", - "method": "POST", + "signal": AbortSignal { + Symbol(kEvents): Map {}, + Symbol(events.maxEventTargetListeners): 10, + Symbol(events.maxEventTargetListenersWarned): false, + Symbol(kHandlers): Map {}, + Symbol(kAborted): false, + Symbol(kReason): undefined, + Symbol(kComposite): false, + }, }, ] Number of calls: 1 Ignored nodes: comments, script, style <html> <head> <title> Choose your role -- StudyHub </title> <meta content="Browse, upload, and collaborate on course study sheets with students at your school." name="description" /> <meta content="Choose your role -- StudyHub" property="og:title" /> <meta content="Browse, upload, and collaborate on course study sheets with students at your school." property="og:description" /> <meta content="website" property="og:type" /> <meta content="http://localhost:3000/" property="og:url" /> <meta content="Choose your role -- StudyHub" name="twitter:title" /> <meta content="Browse, upload, and collaborate on course study sheets with students at your school." name="twitter:description" /> </head> <body> <div> <main style="max-width: 480px; margin: 56px auto; padding: 0px 20px; display: grid; gap: 20px;" > <header style="display: grid; gap: 8px;" > <h1 style="margin: 0px; font-size: 24px; font-weight: 800; color: var(--sh-heading);" > One more step </h1> <p style="margin: 0px; color: var(--sh-subtext); font-size: 14px;" > Tell us how you plan to use StudyHub. You can change this later in Settings. </p> <p style="margin: 0px; color: var(--sh-muted); font-size: 13px;" > Continuing as <strong> new@example.com </strong> </p> </header> <div style="display: grid; gap: 6px;" > <label for="rolepicker-username" style="font-size: 13px; font-weight: 700; color: var(--sh-heading);" > Choose your username </label> <input autocomplete="username" id="rolepicker-username" maxlength="20" placeholder="3-20 chars, letters/numbers/_" style="width: 100%; box-sizing: border-box; padding: 11px 12px; border-radius: 10px; border: 1px solid var(--sh-input-border); background: var(--sh-input-bg, var(--sh-surface)); color: var(--sh-input-text, var(--sh-text)); font-size: 14px; font-family: inherit;" type="text" value="new" /> <span style="font-size: 12px; color: var(--sh-danger-text);" > Already taken. </span> </div> <div style="display: grid; gap: 8px;" > <label style="display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--sh-text);" > <input checked="" type="checkbox" /> Set a password (recommended — used when deleting your account or changing email) </label> <div style="display: grid; gap: 8px;" > <input autocomplete="new-password" placeholder="Password (8+ chars, 1 capital, 1 number)" style="width: 100%; box-sizing: border-box; padding: 11px 12px; border-radius: 10px; border: 1px solid var(--sh-input-border); background: var(--sh-input-bg, var(--sh-surface)); colo
src/pages/auth/RolePickerPage.test.jsx > RolePickerPage > disables Continue until a role is chosen: frontend/studyhub-app/src/pages/auth/RolePickerPage.test.jsx#L77
Error: expect(element).not.toBeDisabled() Received element is disabled: <button disabled="" style="padding: 10px 20px; border-radius: 10px; border: medium; background: var(--sh-brand); color: rgb(255, 255, 255); font-size: 13px; font-weight: 700; cursor: not-allowed; opacity: 0.55;" type="button" /> ❯ src/pages/auth/RolePickerPage.test.jsx:77:29
src/components/ai/AiSheetReport.test.jsx > AiSheetReport > shows the Apply-edit button after a draft is ready (permission-gated): frontend/studyhub-app/src/components/ai/AiSheetReport.test.jsx#L205
TestingLibraryElementError: Unable to find role="button" and name `/edit with ai/i` Ignored nodes: comments, script, style <body> <div> <div style="border: 1px solid var(--sh-border); border-radius: 12px; background: var(--sh-soft); padding: 12px; margin-bottom: 12px; font-size: 12.5px; color: var(--sh-text);" > <header style="display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px;" > <div style="display: flex; align-items: center; gap: 6px;" > <span data-testid="icon-spark" /> <strong style="font-size: 12.5px; color: var(--sh-heading);" > Hub AI · this sheet </strong> </div> </header> <div style="display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px;" > <button style="background: var(--sh-brand); color: rgb(255, 255, 255); border: medium; border-radius: 8px; padding: 6px 10px; font-size: 11.5px; font-weight: 600; cursor: pointer;" type="button" > Analyze sheet </button> </div> <p style="margin: 0px; color: var(--sh-muted); font-size: 11.5px;" > Get an AI report on this sheet (read-only for non-owners). </p> </div> </div> </body> Ignored nodes: comments, script, style <html> <head /> <body> <div> <div style="border: 1px solid var(--sh-border); border-radius: 12px; background: var(--sh-soft); padding: 12px; margin-bottom: 12px; font-size: 12.5px; color: var(--sh-text);" > <header style="display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px;" > <div style="display: flex; align-items: center; gap: 6px;" > <span data-testid="icon-spark" /> <strong style="font-size: 12.5px; color: var(--sh-heading);" > Hub AI · this sheet </strong> </div> </header> <div style="display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px;" > <button style="background: var(--sh-brand); color: rgb(255, 255, 255); border: medium; border-radius: 8px; padding: 6px 10px; font-size: 11.5px; font-weight: 600; cursor: pointer;" type="button" > Analyze sheet </button> </div> <p style="margin: 0px; color: var(--sh-muted); font-size: 11.5px;" > Get an AI report on this sheet (read-only for non-owners). </p> </div> </div> </body> </html> ❯ Module.waitForWrapper ../../node_modules/@testing-library/dom/dist/wait-for.js:163:27 ❯ src/components/ai/AiSheetReport.test.jsx:205:11
src/lib/prefetch.test.js > prefetch module > route endpoint mapping > maps /my-courses to /api/courses/enrolled: frontend/studyhub-app/src/lib/prefetch.test.js#L334
AssertionError: expected "vi.fn()" to be called with arguments: [ …(2) ] Received: 1st vi.fn() call: [ - "http://localhost:4000/api/courses/enrolled", - Any<Object>, + "http://localhost:4000/api/courses/schools", + { + "credentials": "include", + }, ] Number of calls: 1 ❯ src/lib/prefetch.test.js:334:28
backend
Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: actions/checkout@v4. Actions will be forced to run with Node.js 24 by default starting June 2nd, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 24 now, set the FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once Node.js 24 becomes the default, you can temporarily opt out by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
frontend
Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: actions/checkout@v4. Actions will be forced to run with Node.js 24 by default starting June 2nd, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 24 now, set the FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once Node.js 24 becomes the default, you can temporarily opt out by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/