{"record":{"id":"85523866e66b0d7d","repo":"yikart/AiToEarn","slug":"responsecode-configeditorunsupportedformat","errorCode":"ResponseCode.ConfigEditorUnsupportedFormat","errorMessage":"ConfigEditorUnsupportedFormat","messagePattern":"ConfigEditorUnsupportedFormat","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/libs/config-editor/src/config-editor.service.ts","lineNumber":46,"sourceCode":"    this.validateConfigValue(config)\n  }\n\n  async saveConfig(config: Record<string, unknown>) {\n    const configPath = resolve(process.cwd(), this.config.configPath)\n    const format = this.getConfigFileFormat(configPath)\n    const content = this.serializeConfig(this.validateConfigValue(config), format)\n    await this.writeConfigFile(configPath, content)\n  }\n\n  private getConfigFileFormat(filePath: string): ConfigFileFormat {\n    const lowerPath = filePath.toLowerCase()\n    if (lowerPath.endsWith('.json')) {\n      return ConfigFileFormat.Json\n    }\n    if (lowerPath.endsWith('.yaml') || lowerPath.endsWith('.yml')) {\n      return ConfigFileFormat.Yaml\n    }\n    throw new AppException(ResponseCode.ConfigEditorUnsupportedFormat)\n  }\n\n  private parseConfig(content: string, format: ConfigFileFormat) {\n    try {\n      return format === ConfigFileFormat.Json\n        ? JSON.parse(content)\n        : parseYaml(content)\n    }\n    catch (error) {\n      throw new AppException(\n        ResponseCode.ConfigEditorParseFailed,\n        error instanceof Error ? error.message : String(error),\n      )\n    }\n  }\n\n  private validateConfigValue(config: unknown): Record<string, unknown> {\n    const schema = isZodDto(this.config.schema) ? this.config.schema.schema : this.config.schema","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/libs/config-editor/src/config-editor.service.ts#L28-L64","documentation":"ConfigEditorService infers the config file format purely from the file extension of the configured configPath: only .json, .yaml and .yml are supported. If the extension matches neither, getConfigFileFormat throws this AppException before any file I/O happens. It is a configuration-time misuse of the config-editor library, not a runtime data problem.","triggerScenarios":"ConfigEditorService.getConfig(), getConfig() indirectly, or saveConfig() is called while this.config.configPath (resolved against process.cwd()) does not end in .json, .yaml or .yml — e.g. 'config.ini', 'settings', 'app.conf', or '.toml'.","commonSituations":"Pointing the config editor at a TOML/INI/.env/properties file; passing an extensionless path; a typo like 'config.JSONX' or 'config.yml.bak'; mounting the config under a path with a query or suffix appended by a deploy tool.","solutions":["Rename the config file (or change configPath) so it ends with .json, .yaml or .yml","If the underlying format is not JSON/YAML, convert the file content to JSON or YAML and update configPath","If the extension is right but case or casing suffix is wrong, note the check is case-insensitive, so 'CONFIG.JSON' works — fix spelling instead"],"exampleFix":"// before\nConfigEditorModule.register({ configPath: 'config/app.ini', schema: AppSchema })\n// after\nConfigEditorModule.register({ configPath: 'config/app.yaml', schema: AppSchema })","handlingStrategy":"validation","validationCode":"const p = configPath.toLowerCase()\nif (!p.endsWith('.json') && !p.endsWith('.yaml') && !p.endsWith('.yml'))\n  throw new Error(`configPath must be .json/.yaml/.yml, got: ${configPath}`)","typeGuard":"function isSupportedConfigPath(path: string): boolean {\n  return /\\.(json|ya?ml)$/i.test(path)\n}","tryCatchPattern":"try {\n  await editor.getConfig()\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.ConfigEditorUnsupportedFormat)\n    logger.error(`Unsupported config extension: ${cfg.configPath}`)\n  throw e\n}","preventionTips":["Always end configPath with .json, .yaml or .yml","Add a startup assertion on configPath extension before registering the module","Do not point the editor at TOML/INI/.env files — convert them first","Watch for deploy tooling appending suffixes like .bak or .template to config paths"],"tags":["config","file-format","configuration"],"backgroundTag":"unsupported-config-file-format","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}