jackwener/OpenCLI · error · ConfigError
Failed to parse Xiaoyuzhou credential file: ${filePath}
Error message
Failed to parse Xiaoyuzhou credential file: ${filePath} What it means
When reading the xiaoyuzhou credential file fails for any reason other than the missing-token ConfigError, loadXiaoyuzhouCredentials wraps the underlying error in a ConfigError: 'Failed to parse Xiaoyuzhou credential file: <path>' with a hint to ensure the file contains valid JSON (original error appended). Typical cause: fs.readFileSync threw (permissions) or JSON.parse failed on malformed content.
Source
Thrown at clis/xiaoyuzhou/auth.js:62
device_properties: String(raw.device_properties ?? raw.deviceProperties ?? XIAOYUZHOU_DEFAULT_DEVICE_PROPERTIES),
};
}
export function loadXiaoyuzhouCredentials() {
const filePath = getXiaoyuzhouCredentialFile();
if (fs.existsSync(filePath)) {
try {
const parsed = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
const credentials = normalizeXiaoyuzhouCredentials(parsed);
if (!credentials.access_token || !credentials.refresh_token) {
throw new ConfigError(`Xiaoyuzhou credential file is missing access_token or refresh_token: ${filePath}`, 'Recreate the file with valid credentials.');
}
return credentials;
}
catch (error) {
if (error instanceof ConfigError) {
throw error;
}
throw new ConfigError(`Failed to parse Xiaoyuzhou credential file: ${filePath}`, `Ensure ${filePath} contains valid JSON. (${getErrorMessage(error)})`);
}
}
throw new ConfigError(`Missing Xiaoyuzhou credentials. Expected ${filePath}`, `Create ${filePath} with access_token and refresh_token.`);
}
export function saveXiaoyuzhouCredentials(credentials) {
const filePath = getXiaoyuzhouCredentialFile();
fs.mkdirSync(path.dirname(filePath), { recursive: true });
fs.writeFileSync(filePath, `${JSON.stringify({
access_token: credentials.access_token,
refresh_token: credentials.refresh_token,
expires_at: credentials.expires_at,
device_id: credentials.device_id,
device_properties: credentials.device_properties,
}, null, 2)}\n`, 'utf-8');
}
export function shouldRefreshXiaoyuzhouCredentials(credentials, now = getNowMs()) {View on GitHub (pinned to 49907e53dc)
Solutions
- Validate the file: run JSON.parse on its contents (or `node -e "JSON.parse(require('fs').readFileSync('<path>','utf8'))"`) and fix the syntax error reported
- Recreate filePath with clean, complete JSON containing access_token and refresh_token
- Check file permissions/readability for the user running the CLI
- Read the appended getErrorMessage(error) detail in the hint to distinguish parse vs read failures
Example fix
// before (trailing comma → parse error)
{ "access_token": "abc", "refresh_token": "def", }
// after
{ "access_token": "abc", "refresh_token": "def" } Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
function assertValidCredJson(filePath) {
const raw = fs.readFileSync(filePath, 'utf-8');
try { JSON.parse(raw); } catch (e) { throw new Error(`${filePath} is not valid JSON: ${e.message}`); }
}
assertValidCredJson('./config/xiaoyuzhou.credentials.json'); Try / catch
try {
const creds = loadXiaoyuzhouCredentials();
} catch (err) {
if (/Failed to parse Xiaoyuzhou credential file/.test(err.message)) {
fs.copyFileSync(credPath, credPath + '.bak');
await regenerateCredentials(credPath); // rewrite the file as clean JSON
} else throw err;
} Prevention
- Write credential files programmatically (JSON.stringify) instead of by hand
- Validate the file with JSON.parse during setup scripts
- Ensure atomic writes (temp file + rename) so the file is never truncated
- Check file read permissions for the executing user
When it happens
Trigger: Credential file contains invalid JSON (trailing commas, truncation, HTML error page pasted in); file unreadable due to permissions; encoding issues; ConfigError from the token check is intentionally rethrown unwrapped and does NOT produce this message.
Common situations: Editor saved the file as JSON5/with comments; clipboard paste captured extra text; disk-full write left a truncated file; running as a user without read access to the file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Xiaoyuzhou credential file is missing access_token or refres
- Bilibili conclusion API returned malformed model_result JSON
- Boss API request failed: ${message}
- coingecko categories returned malformed JSON: ${err?.message
- coingecko exchanges returned malformed JSON: ${err?.message
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/558f7c7e66fd9f6d.
Report an issue: GitHub.