{"record":{"id":"d2e4fa07080a0ea6","repo":"sveltejs/kit","slug":"cannot-import-app-modules-other-than-app-en","errorCode":null,"errorMessage":"Cannot import `$app/*` modules other than `$app/env` inside `src/env`","messagePattern":"Cannot import `\\$app/\\*` modules other than `\\$app/env` inside `src/env`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/env.js","lineNumber":103,"sourceCode":"\n\t\tif (!variables || typeof variables !== 'object') {\n\t\t\tthrow new Error(`${file} must export a variables object`);\n\t\t}\n\n\t\t// validate\n\t\tfor (const name of Object.keys(variables)) {\n\t\t\tif (!valid_identifier.test(name) || reserved.has(name)) {\n\t\t\t\tthrow new Error(`Invalid environment variable name ${JSON.stringify(name)}`);\n\t\t\t}\n\t\t}\n\t} catch (e) {\n\t\tconst error = /** @type {any} */ (e || {});\n\n\t\tif (\n\t\t\terror.code === 'ERR_MODULE_NOT_FOUND' &&\n\t\t\terror.message?.includes(`Cannot find module '$app`)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot import \\`$app/*\\` modules other than \\`$app/env\\` inside \\`src/env\\``,\n\t\t\t\t{ cause: e }\n\t\t\t);\n\t\t}\n\n\t\tthrow error;\n\t} finally {\n\t\tawait server.close();\n\t}\n\n\treturn { variables, deps };\n}\n\n/**\n * Creates the `<sveltekit:generated>/env/*` modules, keyed by path relative to `dir`. Every module\n * derives from one pass over `variables`, so an inlined value is validated once per build.\n * @param {ValidatedConfig} config\n * @param {Record<string, EnvVarConfig<any>> | null} variables","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/env.js#L85-L121","documentation":"Modules in src/env can only import `$app/env`; importing any other `$app/*` module (like $app/navigation or $app/stores) is prohibited because src/env.js is loaded in a build-time context without the full app runtime. When the dynamic import fails with ERR_MODULE_NOT_FOUND for a `$app` module, SvelteKit rethrows with this clearer message.","triggerScenarios":"src/env.js (or its imports) containing `import { goto } from '$app/navigation'` or any non-env `$app` import; transitively importing an app module that itself imports $app/* modules.","commonSituations":"Reusing a shared module inside src/env.js that pulls in client-side app code; attempting to derive env validation from app stores.","solutions":["Remove all `$app/*` imports other than `$app/env` from src/env.js and everything it imports.","Move shared logic that needs $app modules out of the src/env import graph.","Use only plain Node-compatible code and $app/env inside src/env.js."],"exampleFix":"// before (src/env.js)\nimport { dev } from '$app/environment';\nimport { goto } from '$app/navigation';\nexport const variables = {};\n// after\nimport { dev } from '$app/environment';\nexport const variables = {};","handlingStrategy":"validation","validationCode":"// scan src/env.js and its local imports for forbidden $app modules\nconst src = await fs.readFile('src/env.js', 'utf8');\nconst bad = src.match(/\\$app\\/(?!env\\b)[\\w-]+/g);\nif (bad) throw new Error(`Forbidden imports in src/env.js: ${bad.join(', ')}`);","typeGuard":null,"tryCatchPattern":"try {\n  await build();\n} catch (e) {\n  if (String(e.message).includes('Cannot import `$app/*` modules')) {\n    console.error('src/env.js import graph must only use $app/env — refactor the import out');\n  } else throw e;\n}","preventionTips":["Keep src/env.js dependency-free except for $app/env and plain Node modules.","Audit any shared module before importing it into src/env.js for transitive $app imports.","Only $app/environment (and $app/env) are permitted in the src/env context."],"tags":["env","imports","sveltekit"],"backgroundTag":"forbidden-module-import","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}