{"record":{"id":"0ee9e267c2da2064","repo":"toeverything/AFFiNE","slug":"invalid-config-for-module-module-with-key","errorCode":null,"errorMessage":"Invalid config for module [${module}] with key [${key}]\nValue: ${JSON.stringify(defaultValue)}\nError: ${issue.message}","messagePattern":"Invalid config for module \\[(.+?)\\] with key \\[(.+?)\\]\nValue: (.+?)\nError: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/backend/server/src/base/config/register.ts","lineNumber":370,"sourceCode":"\n  for (const [module, defs] of Object.entries(APP_CONFIG_DESCRIPTORS)) {\n    const modulizedConfig = {};\n\n    for (const [key, desc] of Object.entries(defs)) {\n      let defaultValue = desc.default;\n\n      if (desc.env) {\n        const [env, parser] = desc.env;\n        const envValue = envs[env];\n        if (envValue) {\n          defaultValue = parseEnvValue(envValue, parser);\n        }\n      }\n\n      const { success, error } = desc.validate(defaultValue);\n\n      if (!success) {\n        throw new Error(\n          error.issues\n            .map(issue => {\n              return `Invalid config for module [${module}] with key [${key}]\nValue: ${JSON.stringify(defaultValue)}\nError: ${issue.message}`;\n            })\n            .join('\\n')\n        );\n      }\n\n      set(modulizedConfig, key, defaultValue);\n    }\n\n    // @ts-expect-error all keys are known\n    config[module] = modulizedConfig;\n  }\n\n  CONFIG_JSON_PATHS.forEach(path => {","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/base/config/register.ts#L352-L388","documentation":"During AFFiNE server startup, the config register resolves each key's value (defaults, then env override parsed by parseEnvValue) and validates it with the key's zod validator (desc.validate). On failure it throws an Error listing the module, key, JSON-encoded value, and the zod issue message, aborting boot. So the server refuses to start while any single config value violates its declared schema.","triggerScenarios":"Setting an env var to a value with the wrong type/format for its key (malformed URL, non-numeric value for a number key, invalid boolean); a typo'd or stale override in .env; deploying with env vars from an older incompatible AFFiNE version.","commonSituations":"Docker/Kubernetes env typos in AFFiNE_-prefixed variables; config schema tightened after an upgrade so previously accepted values now fail; copy-pasted .env files between environments.","solutions":["Read the thrown message: it names the exact module and key — fix that env var or override to match the expected type/format.","Check the key's definition in packages/backend/server/src/base/config (its zod schema and env parser) for the accepted format.","Remove stale overrides left over from previous versions.","Validate the full environment in CI (boot the config stage) before deploying."],"exampleFix":"# before\nAFFINE_SERVER_URL=\"not a url\"  # fails url validation for its module/key\n\n# after\nAFFINE_SERVER_URL=\"https://affine.example.com\"","handlingStrategy":"validation","validationCode":"// fail fast at deploy time instead of at server boot\nimport { z } from 'zod';\nconst boolish = z.union([z.boolean(), z.enum(['true', 'false']).transform(v => v === 'true')]);\n// mirror each env key's expected shape and parse process.env before startup","typeGuard":"const isValidEnvValue = (value: string, schema: z.ZodType<unknown>): boolean =>\n  schema.safeParse(value).success;","tryCatchPattern":"try {\n  await app.init(); // config registration runs here\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Invalid config for module')) {\n    // parse module/key from the message, fix the env var, and exit non-zero\n    console.error(e.message);\n    process.exit(1);\n  } else throw e;\n}","preventionTips":["Run the server's config stage in CI with production env to catch invalid values before deploy.","Keep .env files versioned per environment and diff them after upgrades.","Read each key's zod definition in packages/backend/server/src/base/config when unsure of the accepted format."],"tags":["config","env","zod","validation","server","affine"],"backgroundTag":"invalid-config-value","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}