jackwener/OpenCLI · error · CommandExecutionError

Failed to parse settings.json: ${e.message}

Error message

Failed to parse settings.json: ${e.message}

What it means

Thrown when settings.json content, after stripping JSON comments and trailing commas, still fails JSON.parse. The library pre-cleans the file (removing /* */ and // comments, trailing commas) but cannot repair malformed JSON, so it wraps the parser message in a CommandExecutionError.

Source

Thrown at clis/trae-solo/settings.js:43

    domain: 'localhost',
    strategy: Strategy.LOCAL,
    browser: false,
    args: [],
    columns: ['Field', 'Value'],
    func: async () => {
        if (!fs.existsSync(TRAE_SETTINGS_JSON)) {
            throw new EmptyResultError('trae-solo settings-read', `settings.json not found: ${TRAE_SETTINGS_JSON}`);
        }
        const raw = fs.readFileSync(TRAE_SETTINGS_JSON, 'utf-8');
        // Strip JSONC: line comments + block comments + trailing commas.
        const stripped = raw
            .replace(/\/\*[\s\S]*?\*\//g, '')
            .replace(/^\s*\/\/.*$/gm, '')
            .replace(/([^:"])\/\/.*$/gm, '$1')
            .replace(/,(\s*[}\]])/g, '$1');
        let obj;
        try { obj = JSON.parse(stripped); } catch (e) {
            throw new CommandExecutionError(`Failed to parse settings.json: ${e.message}`, '');
        }
        const rows = [];
        for (const [k, v] of Object.entries(obj)) {
            rows.push({ Field: k, Value: typeof v === 'object' ? JSON.stringify(v) : String(v) });
        }
        if (!rows.length) {
            throw new EmptyResultError('trae-solo settings-read', 'settings.json is empty (or contains only defaults).');
        }
        return rows;
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the settings file and validate it with JSON.parse or a linter; fix the syntax error named in the message.
  2. Check whether a '//' inside a string value (e.g. a URL) was stripped; wrap such values properly and re-check.
  3. Restore the file from backup or delete it so trae regenerates defaults.
  4. If the file is fine natively, remember this parser is JSONC-style: ensure the file only uses comments/trailing commas the stripper supports.

Example fix

// before (settings.json)
{ "endpoint": "https://api.example.com", // comment
// after
{ "endpoint": "https://api.example.com" }
Defensive patterns

Strategy: try-catch

Validate before calling

const fs = require('fs');
function validateSettingsJson(p) {
  const raw = fs.readFileSync(p, 'utf-8');
  const stripped = raw.replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, '').replace(/([^:"])\/\/.*$/gm, '$1').replace(/,(\s*[}\]])/g, '$1');
  try { JSON.parse(stripped); return true; } catch { return false; }
}

Type guard

function isParsableJson(text) {
  try { JSON.parse(text); return true; } catch { return false; }
}

Try / catch

try {
  const rows = await settingsRead();
} catch (e) {
  if (e instanceof CommandExecutionError && /Failed to parse settings\.json/.test(e.message)) {
    // back up the file and repair or restore defaults
  } else throw e;
}

Prevention

When it happens

Trigger: Running the trae-solo settings-read command when ~/.trae/settings.json (or the configured settings file) contains malformed JSON — e.g. an unquoted key, a missing value, a stray comment the regex stripper mangles (like a '//' inside a URL value), or truncated content.

Common situations: Hand-edited settings files; editor auto-saves mid-write; URL values like 'https://x' hit by the // stripping regex; copy-pasted settings with smart quotes; a file written by an older trae version with a schema the stripper corrupts.

Understand the failure class

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/709baf267d7cc5ab. Report an issue: GitHub.