yikart/AiToEarn · error · AppException

ResponseCode.ConfigEditorUnsupportedFormat

ResponseCode.ConfigEditorUnsupportedFormat

Error message

ConfigEditorUnsupportedFormat

What it means

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.

Source

Thrown at project/aitoearn-backend/libs/config-editor/src/config-editor.service.ts:46

    this.validateConfigValue(config)
  }

  async saveConfig(config: Record<string, unknown>) {
    const configPath = resolve(process.cwd(), this.config.configPath)
    const format = this.getConfigFileFormat(configPath)
    const content = this.serializeConfig(this.validateConfigValue(config), format)
    await this.writeConfigFile(configPath, content)
  }

  private getConfigFileFormat(filePath: string): ConfigFileFormat {
    const lowerPath = filePath.toLowerCase()
    if (lowerPath.endsWith('.json')) {
      return ConfigFileFormat.Json
    }
    if (lowerPath.endsWith('.yaml') || lowerPath.endsWith('.yml')) {
      return ConfigFileFormat.Yaml
    }
    throw new AppException(ResponseCode.ConfigEditorUnsupportedFormat)
  }

  private parseConfig(content: string, format: ConfigFileFormat) {
    try {
      return format === ConfigFileFormat.Json
        ? JSON.parse(content)
        : parseYaml(content)
    }
    catch (error) {
      throw new AppException(
        ResponseCode.ConfigEditorParseFailed,
        error instanceof Error ? error.message : String(error),
      )
    }
  }

  private validateConfigValue(config: unknown): Record<string, unknown> {
    const schema = isZodDto(this.config.schema) ? this.config.schema.schema : this.config.schema

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Rename the config file (or change configPath) so it ends with .json, .yaml or .yml
  2. If the underlying format is not JSON/YAML, convert the file content to JSON or YAML and update configPath
  3. 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

Example fix

// before
ConfigEditorModule.register({ configPath: 'config/app.ini', schema: AppSchema })
// after
ConfigEditorModule.register({ configPath: 'config/app.yaml', schema: AppSchema })
Defensive patterns

Strategy: validation

Validate before calling

const p = configPath.toLowerCase()
if (!p.endsWith('.json') && !p.endsWith('.yaml') && !p.endsWith('.yml'))
  throw new Error(`configPath must be .json/.yaml/.yml, got: ${configPath}`)

Type guard

function isSupportedConfigPath(path: string): boolean {
  return /\.(json|ya?ml)$/i.test(path)
}

Try / catch

try {
  await editor.getConfig()
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.ConfigEditorUnsupportedFormat)
    logger.error(`Unsupported config extension: ${cfg.configPath}`)
  throw e
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/85523866e66b0d7d. Report an issue: GitHub.