{"record":{"id":"55e4f793d67d7b1e","repo":"slopus/happy","slug":"handy-master-secret-is-required","errorCode":null,"errorMessage":"HANDY_MASTER_SECRET is required","messagePattern":"HANDY_MASTER_SECRET is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/happy-server/sources/standalone.ts","lineNumber":118,"sourceCode":"    }\n\n    if (appliedCount === 0) {\n        console.log(\"No new migrations to apply.\");\n    } else {\n        console.log(`Applied ${appliedCount} migration(s).`);\n    }\n\n    await pg.close();\n}\n\nasync function serve() {\n    // Ensure DB_PROVIDER is set for db.ts\n    process.env.DB_PROVIDER = process.env.DB_PROVIDER || \"pglite\";\n    process.env.PGLITE_DIR = process.env.PGLITE_DIR || pgliteDir;\n\n    const masterSecret = process.env.HANDY_MASTER_SECRET;\n    if (!masterSecret) {\n        throw new Error(\"HANDY_MASTER_SECRET is required\");\n    }\n\n    const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 3005;\n    const host = process.env.HOST || \"0.0.0.0\";\n    const staticDir = findStaticDir();\n    let injectHtmlConfig: Record<string, unknown> | undefined;\n    if (process.env.HAPPY_INJECT_HTML_CONFIG) {\n        try {\n            injectHtmlConfig = JSON.parse(process.env.HAPPY_INJECT_HTML_CONFIG);\n        } catch {\n            // ignore malformed input\n        }\n    }\n\n    const { startServer } = await import(\"./index\");\n    await startServer({\n        pgliteDir: process.env.PGLITE_DIR!,\n        masterSecret,","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-server/sources/standalone.ts#L100-L136","documentation":"serve() refuses to start the standalone server when the HANDY_MASTER_SECRET environment variable is unset or empty. This secret is required to sign/encrypt session tokens, so without it the server cannot operate securely.","triggerScenarios":"Starting the standalone happy-server (e.g. via the CLI's happyServer launcher) without HANDY_MASTER_SECRET in the environment, or with it set to an empty string.","commonSituations":"Missing .env file in the working directory; running the server in Docker/CI where the env var wasn't passed through; typo in the variable name (e.g. HAPPY_MASTER_SECRET); relying on a default that was removed in a newer version.","solutions":["Set HANDY_MASTER_SECRET in the environment before starting the server (export HANDY_MASTER_SECRET=$(openssl rand -hex 32) or add it to .env)","If running in Docker/CI, pass the variable explicitly (docker run -e HANDY_MASTER_SECRET=... / secrets manager)","Check for typos and that the .env file is actually loaded from the expected working directory"],"exampleFix":"// before\n$ npx happy-server\nError: HANDY_MASTER_SECRET is required\n// after\n$ export HANDY_MASTER_SECRET=$(openssl rand -hex 32)\n$ npx happy-server","handlingStrategy":"validation","validationCode":"if (!process.env.HANDY_MASTER_SECRET) {\n  throw new Error('HANDY_MASTER_SECRET is required (export HANDY_MASTER_SECRET=$(openssl rand -hex 32))');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add HANDY_MASTER_SECRET to your .env and commit .env.example documenting it","Use a secrets manager in Docker/CI and pass the var explicitly","Validate required env vars at process start with a schema library (zod/env-var)","Check for typos: the variable is HANDY_MASTER_SECRET, not HAPPY_MASTER_SECRET"],"tags":["configuration","env","security","startup"],"backgroundTag":"missing-env-var","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}