Bug: session destroy fails for addresses with different casing on case-sensitive filesystems
- Dominant language
- TypeScript
- Stars
- 172
- Forks
- 207
- Avg merge
- 49m
- Merged PRs (30d)
- 1
Description
### Describe the bug
`account-cli session destroy` fails on case-sensitive filesystems when the address casing provided by the user differs from the casing stored in the session file.
### Steps
1. On Linux/WSL, create an external EOA session stored as:
`external-eoa-0xEoa444.json`
2. Confirm the session is detected:
`BASE_ACCOUNT_DIR="$REPRO_DIR" npx tsx packages/account-cli/src/index.ts session list --json`
The CLI lists the session with `eoa: "0xEoa444"`.
3. Attempt to destroy the session using the same address with different casing:
`BASE_ACCOUNT_DIR="$REPRO_DIR" npx tsx packages/account-cli/src/index.ts session destroy 0xeoa444 --json`
Actual result:
`INVALID_INPUT: Session not found for external-eoa:0xeoa444`
The original `external-eoa-0xEoa444.json` file remains on disk.
4. Repeat the destroy attempt with an explicit mode:
`BASE_ACCOUNT_DIR="$REPRO_DIR" npx tsx packages/account-cli/src/index.ts session destroy 0xeoa444 --mode external-eoa --json`
The same `INVALID_INPUT` error is returned and the session file remains.
5. As a control, destroy the session using the exact stored casing:
`BASE_ACCOUNT_DIR="$REPRO_DIR" npx tsx packages/account-cli/src/index.ts session destroy 0xEoa444 --json`
6. Observe that the exact-casing command succeeds with:
`status: destroyed`
and the session file is removed.
### Expected behavior
Session identifiers representing Ethereum addresses should be handled consistently regardless of address casing.
If a stored session has the identifier `0xEoa444`, destroying it using `0xeoa444` should resolve and delete the same session.
This should also work when `--mode external-eoa` is provided.
### Version
Current master — commit ededed6a6befdbea3a9508afc9d22bfc14a8e6a3
### Additional info
The lookup path without `--mode` already performs a case-insensitive comparison using `identifier.toLowerCase()` and `sessionKey(s).toLowerCase()`.
However, after finding a matching session, the command calls:
`destroySession(match.mode, identifier);`
This passes the user-provided casing instead of the actual stored session key.
`destroySession()` then constructs the session filename using that identifier. On a case-sensitive filesystem, a stored file such as `external-eoa-0xEoa444.json` does not match the path generated from `0xeoa444`.
The explicit `--mode` path similarly calls:
`destroySession(mode, identifier);`
without first resolving the stored session identifier case-insensitively.
A possible fix for the matched-session path would be:
`destroySession(match.mode, sessionKey(match));`
The explicit `--mode` path may also need case-insensitive session resolution before deletion.
The current integration test destroys the session using the exact same casing as the stored identifier, so this scenario is not currently covered.
Baseline verification before reproduction:
- Existing session integration tests: 15/15 passed
- Working tree clean
- Node.js v24.20.0
- Yarn 4.8.1
- Current master: ededed6a6befdbea3a9508afc9d22bfc14a8e6a3
### Desktop
OS: Linux via WSL
Node.js: v24.20.0
Yarn: 4.8.1
Filesystem: case-sensitive Linux filesystem
Repository: base/account-sdk
Branch: master
Commit: ededed6a6befdbea3a9508afc9d22bfc14a8e6a3
### Smartphone
N/A — this is an account-cli filesystem/session handling issue and is not smartphone-specific.
Contributor guide
Research direction
Start at packages/account-cli/src/index.ts and trace the session destroy paths, including the calls to destroySession() described in the issue. Run the existing session integration tests, then add coverage for differently cased identifiers with and without --mode; done means both commands resolve and remove the stored session on a case-sensitive filesystem.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100