yikart/AiToEarn · error · AppException
ResponseCode.ConfigEditorParseFailed
ResponseCode.ConfigEditorParseFailed
Error message
ConfigEditorParseFailed: error.message
What it means
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.
Source
Thrown at project/aitoearn-backend/libs/config-editor/src/config-editor.service.ts:56
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
if (!(schema instanceof z.ZodType)) {
throw new AppException(ResponseCode.ConfigEditorValidationFailed)
}
const result = schema.safeParse(config)
if (!result.success) {
throw new AppException(ResponseCode.ConfigEditorValidationFailed, z.prettifyError(result.error))
}
return result.data as Record<string, unknown>
}View on GitHub (pinned to d3aa8bea5b)
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
Example fix
// before (config.json)
{ "port": 3000, }
// after
{ "port": 3000 } Defensive patterns
Strategy: validation
Validate before calling
const content = await readFile(configPath, 'utf8')
if (configPath.endsWith('.json')) JSON.parse(content)
else parseYaml(content) // throws locally with the same parser message Type guard
function isParseableJson(s: string): boolean {
try { JSON.parse(s); return true } catch { return false }
} Try / catch
try {
await editor.getConfig()
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.ConfigEditorParseFailed)
logger.error(`Config file syntax error: ${e.message}`)
throw e
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/c1e7097f004d27c7.
Report an issue: GitHub.