Tencent/matrix · error · ProcStatUtil.ParseException
Couldn't read string!
Error message
Couldn't read string!
What it means
ProcStatReader.readWord() builds a whitespace-delimited token; if the very first character it reads is not a valid word character it cannot form any token and throws ParseException("Couldn't read string!"). This means the lexer found an unexpected character where a token was expected.
Solutions
- Catch ParseException in the caller and skip this sample tick; proc stat anomalies are usually transient.
- Inspect the actual /proc/<pid>/stat content on the failing device and validate it before parsing.
- Switch to ProcStatUtil.parseWithBuffer (byte-buffer based) which handles the parenthesized comm field differently.
- Retry on the next poll; a republished process or new tick typically parses fine.
Example fix
// before
CharBuffer word = reader.state();
// after
CharBuffer word;
try {
word = reader.state();
} catch (ProcStatUtil.ParseException e) {
return null; // skip malformed stat sample
} Defensive patterns
Strategy: try-catch
Validate before calling
byte[] head = readFirstBytes("/proc/" + pid + "/stat", 64);
if (head == null || head.length == 0) { /* skip pid */ } Try / catch
try { CharBuffer w = reader.state(); } catch (ProcStatUtil.ParseException e) { return null; } Prevention
- Skip pids whose stat file is empty or unreadable
- Retry on the next tick rather than reusing a failed reader
- Validate raw stat format once on new device models
- Fall back to parseWithBuffer
When it happens
Trigger: Calling state() (which uses readWord) when the current stream position starts on a character that fails the word-character predicate on the first iteration (isFirstRun).
Common situations: Peculiar /proc stat formatting on some kernels or emulators where the expected field is missing, empty, or preceded by unexpected characters; misaligned field offsets after a prior parse error.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/008d852d7a2aed3e.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatReader.java:145
public CharBuffer readWord(CharBuffer buffer) {
buffer.clear();
boolean isFirstRun = true;
while (hasNext()) {
next();
if (!Character.isWhitespace(mChar)) {
if (!buffer.hasRemaining()) {
CharBuffer newBuffer = CharBuffer.allocate(buffer.capacity() * 2);
buffer.flip();
newBuffer.put(buffer);
buffer = newBuffer;
}
buffer.put(mChar);
} else if (isFirstRun) {
throw new ParseException("Couldn't read string!");
} else {
rewind();
break;
}
isFirstRun = false;
}
if (isFirstRun) {
throw new ParseException("Couldn't read string because file ended!");
}
buffer.flip();
return buffer;
}
public long readNumber() {
long sign = 1;View on GitHub (pinned to 3b8293bd65)