{"record":{"id":"878d4913f19a6ab6","repo":"HeyPuter/puter","slug":"must-login-or-signup","errorCode":"must_login_or_signup","errorMessage":"Temporary accounts are disabled","messagePattern":"Temporary accounts are disabled","errorType":"http","errorClass":"HttpError","httpStatus":403,"severity":"warning","filePath":"src/backend/controllers/auth/AuthController.ts","lineNumber":909,"sourceCode":"        }\n        if (!validateEvent.allow) {\n            // Pass the trail id back to a blocked user as the Request Code (when\n            // the harness stamped one), embedded in the message so the existing\n            // signup-block UI surfaces it without a GUI change.\n            const requestCode = validateEvent.trail_id;\n            throw new HttpError(\n                403,\n                (validateEvent.message ?? 'Signup blocked') +\n                    (requestCode ? ` Request Code: ${requestCode}` : ''),\n                {\n                    ...(validateEvent.code\n                        ? { legacyCode: validateEvent.code as never }\n                        : {}),\n                },\n            );\n        }\n        if (is_temp && validateEvent.no_temp_user) {\n            throw new HttpError(\n                403,\n                validateEvent.message ?? 'Temporary accounts are disabled',\n                {\n                    legacyCode: 'must_login_or_signup',\n                    ...(validateEvent.code\n                        ? { legacyCode: validateEvent.code as never }\n                        : {}),\n                },\n            );\n        }\n        const force_email_confirmation = Boolean(\n            validateEvent.requires_email_confirmation,\n        );\n        const force_phone_verification =\n            Boolean(validateEvent.requires_phone_verification) ||\n            // Test/QA switch: force the SMS gate on every signup regardless of\n            // reputation (see config.always_require_phone_verification).\n            Boolean(this.config.always_require_phone_verification);","sourceCodeStart":891,"sourceCodeEnd":927,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/auth/AuthController.ts#L891-L927","documentation":"Thrown by POST /signup (HTTP 403, legacyCode 'must_login_or_signup') when the request is a temp signup (is_temp:true) AND the 'puter.signup.validate' extension set validateEvent.no_temp_user = true. It runs immediately after the abuse 'allow' gate, so it specifically signals that anonymous/temp accounts have been turned off by policy even though signups as a whole may be permitted. validateEvent.message overrides the default text if the extension supplied one.","triggerScenarios":"POST /signup with is_temp:true on a deployment whose abuse-prevention extension disables temp users (no_temp_user=true). A real (non-temp) signup on the same deployment may still succeed.","commonSituations":"A deployment that requires real accounts and uses the validate hook to forbid temp users; an extension policy toggled on after launch, breaking clients that relied on temp-account creation; a client defaulting to is_temp:true for anonymous use.","solutions":["Switch the client to a real signup (is_temp absent/false) with a username/email/password if anonymous access is no longer allowed.","If you operate the server and temp users should be allowed, update the abuse-prevention extension so it does not set no_temp_user for this traffic.","Catch this error specifically and redirect the user to the full signup or login flow rather than retrying the temp request."],"exampleFix":"// before\nawait signup({ is_temp: true });\n\n// after\ntry {\n  await signup({ is_temp: true });\n} catch (e) {\n  if (e.statusCode === 403 && e.legacyCode === 'must_login_or_signup') {\n    openSignupForm(); // real signup with email/password\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// no client pre-check exists; if your server exposes the policy, check it\nif (policy disables temp users) { openRealSignupForm(); return; }","typeGuard":null,"tryCatchPattern":"try {\n  await signup({ is_temp: true });\n} catch (e) {\n  if (e.statusCode === 403 && e.legacyCode === 'must_login_or_signup') {\n    openSignupForm(); // real signup\n  } else throw e;\n}","preventionTips":["Don't default clients to is_temp:true if the deployment forbids temp users.","Catch must_login_or_signup and redirect to a full signup or login.","If temp users should be allowed, ensure the abuse extension doesn't set no_temp_user."],"tags":["auth","signup","temp-user","abuse-prevention","forbidden"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}