Repository navigation
[Hackathon] fix(cli): an unreadable credentials file crashes doctor and offline commands in the telemetry pre-action hook #465
Description
Verified against (commit SHA or released version)
commit 988c035 (main, v0.14.0), built and run on Windows 11, Node 24.16.
Discord Username / User ID
gradzzz
What does this improvement do?
testsprite doctor is written to survive an unreadable credentials file. When the read fails with EPERM or EACCES (the Windows ACL lock-out from #304; #356 stops new files from being locked, but it is not on npm yet, where the latest is 0.14.0), doctor reports the problem and how to recover (doctor.ts#L103-L124).
Users never get to see that. The preAction hook resolves telemetry auth before any command's action runs, with no try/catch (index.ts#L303-L307). It calls resolveTelemetryAuth, then loadConfig, then readFileSync (credentials.ts#L194). So the raw fs error ends the process.
Reproduction: HOME/USERPROFILE point at a temp directory whose .testsprite/credentials has a deny-read entry (icacls credentials /deny %USERNAME%:(R)), and the endpoint points at a closed local port.
> testsprite doctor
Error: EPERM: operation not permitted, open '...\.testsprite\credentials'
# exit 1
> set TESTSPRITE_NO_TELEMETRY=1
> testsprite doctor
[FAIL] Credentials credentials file exists but cannot be read (EPERM); its ACL may be locked out by an earlier CLI version — delete the file and re-run `testsprite setup`
Commands that never need the key fail too while telemetry is on, which is the default. testsprite agent list and testsprite test lint --plan-from plan.json both print the same raw EPERM and exit 1. With TESTSPRITE_NO_TELEMETRY=1 they run normally.
telemetry.ts states the contract: "every failure is swallowed; telemetry NEVER changes a command's behavior, output, or exit code". The send path follows it; the auth lookup in the hook does not.
Details / implementation notes
- Make the telemetry auth lookup best-effort. Any error leaves
telemetryAuthunset, so no event is sent, and the command runs and reports the problem its own way:doctordegrades as designed;- commands that need the key fail through their normal error path;
- offline commands just work.
- Under
--debug, log the swallowed error, like the skill-nudge path does (fix(skill-nudge): log swallowed errors in debug mode #317), so it stays diagnosable. - Tests:
- a credentials read that throws EPERM:
doctorreports the Credentials failure instead of crashing, an offline command exits 0, and no telemetry event is sent; - a unit test for the best-effort lookup.
- a credentials read that throws EPERM:
Relation to #438, which covers a credentials path that is a directory or a named pipe in the credentials reader and doctor: this issue is the hook that runs before every command. Its fix is independent (index.ts / telemetry.ts only). It covers the EPERM case that doctor already handles, and #438's "doctor reports it under Credentials" relies on it while telemetry is on.
Confirmations
- I have searched existing issues and this is not a duplicate.
- I have provided my Discord identity above for reward coordination.
Activity
fyZhang66 commentedon Oct 20, 2026
Confirmed on v0.15.0, thanks @freddy-tama. The
preActiontelemetry hook callsresolveTelemetryAuthwithout a try/catch, so an unreadable credentials file (EPERM/EACCES) crashes every command beforedoctorcan report it. Accepted, scope:--debug; the command runs as if telemetry were off.doctorandcompletionstill run and no beacon is sent.No new dependency. Comment
/assignto claim it.Davidson3556 commentedon Oct 21, 2026
/assign
testsprite-hob commentedon Oct 21, 2026
Assigned to @Davidson3556. Thanks for taking this on. (0 more slots available.)
Your open assigned issues (3/3):
testsprite-hob commentedon Oct 22, 2026
@Davidson3556, your claim on this issue expires in about 24 hours unless you open a PR that links it (for example,
Closes #465orPart of #465). You can re-claim later with/assignif the issue is still free.