{"record":{"id":"ceac6884902e3883","repo":"toeverything/AFFiNE","slug":"invalid-app-config-input-ceac68","errorCode":"invalid_app_config_input","errorMessage":"Invalid app config input: ${message}","messagePattern":"Invalid app config input: (.+?)","errorType":"http","errorClass":"InvalidAppConfigInput","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/data/commands/import.ts","lineNumber":52,"sourceCode":"      }\n\n      Object.entries(config).forEach(([key, value]) => {\n        forValidation.push({\n          module,\n          key,\n          value,\n        });\n        forSaving.push({\n          key: `${module}.${key}`,\n          value,\n        });\n      });\n    });\n\n    const errors = this.configFactory.validate(forValidation);\n\n    if (errors?.length) {\n      throw new InvalidAppConfigInput({\n        message: errors.map(error => error.message).join('\\n '),\n      });\n    }\n\n    // @ts-expect-error null as user id\n    await this.models.appConfig.save(null, forSaving);\n  }\n}\n","sourceCodeStart":34,"sourceCodeEnd":61,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/data/commands/import.ts#L34-L61","documentation":"Thrown by `ImportConfigCommand.execute` after `configFactory.validate(forValidation)` returns one or more validation errors for the imported JSON config. Each error's message is concatenated (newline-separated) into the thrown `InvalidAppConfigInput`. Coded `invalid_app_config_input` (invalid_input) with `{ message }`.","triggerScenarios":"Importing a config JSON whose keys exist but whose values fail schema validation — wrong type, out-of-range number, unrecognized enum, malformed URL/string format, or a value the configured validator rejects.","commonSituations":"Hand-edited config file with a typo (`true`/`false` as a string where a boolean is required, or a number where a string is expected); a key renamed across versions but the file still uses the old shape; environment-specific value (URL) that doesn't match the allowed pattern; copy-paste from a different deployment.","solutions":["Read the concatenated messages in the error — each line names the failing field and the constraint violated.","Compare each value against the config schema/validator for that module and key.","Validate the JSON file locally with the same `configFactory.validate` before importing.","If a key was renamed/removed in an upgrade, regenerate the export from a known-good workspace and diff."],"exampleFix":"// before\n{ \"auth\": { \"sessionTtl\": \"3600\" } } // string where number expected\n\n// after\n{ \"auth\": { \"sessionTtl\": 3600 } }","handlingStrategy":"validation","validationCode":"// Validate locally with the same factory before importing\nconst errors = configFactory.validate(toValidationShape(overrides));\nif (errors?.length) {\n  for (const e of errors) console.error(e.message);\n  process.exit(1);\n}\nawait importConfig.execute(file);","typeGuard":"function isValidConfig(errors) {\n  return !errors || errors.length === 0;\n}","tryCatchPattern":"try {\n  await importConfig.execute(file);\n} catch (e) {\n  if (e.code === 'invalid_app_config_input') {\n    console.error(e.data.message); // concatenated validation messages\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Validate the JSON against the schema before importing.","Export a known-good config and diff your changes against it.","Watch for type mismatches (string vs number/boolean) after hand-editing."],"tags":["cli","config","import","validation","nestjs"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}