Skip to content

fix: check keystore file exists after createKeypairByName to prevent ENOENT crash#378

Open
ygd58 wants to merge 5 commits into
genlayerlabs:v0.40-devfrom
ygd58:fix/getAccount-enoent-crash
Open

fix: check keystore file exists after createKeypairByName to prevent ENOENT crash#378
ygd58 wants to merge 5 commits into
genlayerlabs:v0.40-devfrom
ygd58:fix/getAccount-enoent-crash

Conversation

@ygd58

@ygd58 ygd58 commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Fixes an unhandled ENOENT crash in getAccount() when createKeypairByName() fails to create the keystore file.

Problem

decryptedPrivateKey = await this.createKeypairByName(accountName, false);
// No check here!
keystoreJson = readFileSync(keystorePath, "utf-8"); // crashes with ENOENT

If createKeypairByName fails for any reason other than password mismatch (disk full, permissions error, etc.), the keystore file is never created. The code then crashes with an unhandled ENOENT error instead of showing a clear message.

Fixes #304

Fix

Add an existsSync check after createKeypairByName and call failSpinner with a descriptive message if the file was not created.

ygd58 added 5 commits July 9, 2026 15:33
…abs#305)

The reset() method had dead code:
- delete config[key] removed the key from the in-memory object
- writeConfig(key, undefined) then wrote key=undefined back to disk

Replace both lines with removeConfig(key) which correctly
deletes the key and persists the change to disk.

Fixes genlayerlabs#305
…rompt (genlayerlabs#306)

Previously, passing an empty string to setNetwork() was treated as a
valid network name due to the condition:

  if (networkName || networkName === "")

This caused the command to search for a network named "" and always
fail instead of falling through to the interactive prompt.

Fix: simplify the condition to `if (networkName)` so empty strings
are treated the same as undefined, correctly triggering the interactive
network selection prompt.

Fixes genlayerlabs#306
…erlabs#307)

Two import statements were incorrectly placed in the middle of the file
between the resolveNetwork() function and the BaseAction class definition:

  import { ethers } from 'ethers';
  import { writeFileSync, existsSync, readFileSync } from 'fs';

Move them to the top of the file with all other imports.

Fixes genlayerlabs#307
…assification (genlayerlabs#302)

Three bugs fixed in BaseAction.decryptKeystore():

1. Dead code: after failSpinner(process.exit), the recursive call
   was unreachable. Added explicit return after failSpinner.

2. Potential infinite recursion: if failSpinner did not exit,
   recursion continued without bound. Now returns empty string
   after max attempts to guarantee termination.

3. Wrong error classification: all errors from fromEncryptedJson
   were treated as wrong password. Now re-throws non-password errors
   (corrupted keystore, malformed JSON) immediately with a clear message.

Fixes genlayerlabs#302
…ENOENT crash (genlayerlabs#304)

getAccount() unconditionally called readFileSync after createKeypairByName
even if the latter failed to create the file (e.g. disk full, permissions).
This caused an unhandled ENOENT crash instead of a clear error message.

Add an existsSync check after createKeypairByName and fail with a
descriptive message if the keystore file was not created.

Fixes genlayerlabs#304
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@ygd58, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 22d83e39-ee05-4f3d-ad90-6ead61d50595

📥 Commits

Reviewing files that changed from the base of the PR and between 3396474 and d116e5c.

📒 Files selected for processing (3)
  • src/commands/config/getSetReset.ts
  • src/commands/network/setNetwork.ts
  • src/lib/actions/BaseAction.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot changed the base branch from main to v0.40-dev July 9, 2026 13:46
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

This PR targeted main, which is only the default/static branch.

I retargeted it to v0.40-dev, the active development branch. Pushes to v0.40-dev automatically fast-forward main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] getAccount proceeds with file read after createKeypairByName failure causing unhandled ENOENT crash

1 participant