{"record":{"id":"c1e7097f004d27c7","repo":"yikart/AiToEarn","slug":"responsecode-configeditorparsefailed","errorCode":"ResponseCode.ConfigEditorParseFailed","errorMessage":"ConfigEditorParseFailed: error.message","messagePattern":"ConfigEditorParseFailed: error\\.message","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/libs/config-editor/src/config-editor.service.ts","lineNumber":56,"sourceCode":"  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\n    if (!(schema instanceof z.ZodType)) {\n      throw new AppException(ResponseCode.ConfigEditorValidationFailed)\n    }\n\n    const result = schema.safeParse(config)\n    if (!result.success) {\n      throw new AppException(ResponseCode.ConfigEditorValidationFailed, z.prettifyError(result.error))\n    }\n    return result.data as Record<string, unknown>\n  }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/libs/config-editor/src/config-editor.service.ts#L38-L74","documentation":"When the config file content cannot be parsed as the format inferred from its extension (JSON.parse for .json, the 'yaml' package's parse for .yaml/.yml), parseConfig wraps the underlying parser error in AppException(ConfigEditorParseFailed) with the parser's message. The message field therefore carries the exact JSON/YAML syntax error, including position info for YAML.","triggerScenarios":"readConfigFile returned content that JSON.parse or parseYaml rejects: trailing commas in JSON, comments in JSON, single quotes in JSON keys, tabs in YAML, unclosed brackets/quotes, duplicated keys where the parser forbids them, or an empty file parsed as JSON.","commonSituations":"A hand-edited config file saved with a syntax error; a .json file that is actually YAML (or vice versa); a template/placeholder file never filled in; a CI step writing partial content before the app reads it; encoding issues (BOM) that break JSON.parse.","solutions":["Read the nested message (e.g. 'Unexpected token } in JSON at position 42') and fix that exact spot in the config file","Validate the file with a JSON/YAML linter or `node -e \"JSON.parse(require('fs').readFileSync(path,'utf8'))\"` before starting the app","Verify the file extension matches the actual content format (real JSON in .json, real YAML in .yaml/.yml)","Strip a UTF-8 BOM or re-save the file as plain UTF-8"],"exampleFix":"// before (config.json)\n{ \"port\": 3000, }\n// after\n{ \"port\": 3000 }","handlingStrategy":"validation","validationCode":"const content = await readFile(configPath, 'utf8')\nif (configPath.endsWith('.json')) JSON.parse(content)\nelse parseYaml(content) // throws locally with the same parser message","typeGuard":"function isParseableJson(s: string): boolean {\n  try { JSON.parse(s); return true } catch { return false }\n}","tryCatchPattern":"try {\n  await editor.getConfig()\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.ConfigEditorParseFailed)\n    logger.error(`Config file syntax error: ${e.message}`)\n  throw e\n}","preventionTips":["Validate the config file with JSON/YAML linters in CI before deploy","Keep file extension and actual content format aligned","Never hand-edit production configs without a parse check","Save files as plain UTF-8 without BOM"],"tags":["config","parsing","json","yaml"],"backgroundTag":"config-parse-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}