Summary
get_config_dir() silently falls back to the current working directory (./) when the user's home directory cannot be resolved, causing the CLI to create ./.txio/ — and store the auth token and config.json there — in whatever directory the command happens to be run from, with no warning to the user.
Background
get_config_dir() in src/utils/mod.rs (lines 56-65) calls dirs_next::home_dir() to locate the user's home directory, and falls back to PathBuf::from(".") when that call returns None. dirs_next::home_dir() returns None in several realistic environments: minimal containers without a populated HOME env var or /etc/passwd entry, some CI runners, sandboxed/chrooted environments, or misconfigured shells.
When this fallback triggers, the CLI silently creates ./.txio/ — a directory relative to wherever the current process's working directory happens to be — instead of a true, stable home directory. This has two concrete consequences:
- Inconsistent credential location: the JWT token and config.json end up in a directory whose permissions, lifecycle, and backup/cleanup behavior are entirely different from
~/.txio/. A CI job or container that gets torn down after each run would silently lose "persisted" credentials every time, defeating the purpose of persistence, without any error being surfaced.
- Accidental credential exposure: if
txio is run from inside a project directory (e.g., a developer testing the CLI from within a git-tracked repo), the fallback creates ./.txio/ inside that project. If the directory isn't already gitignored, the auth token and config file — potentially containing secrets — could end up staged or committed to a git repository, a significantly worse outcome than simply failing to persist state.
This is a silent footgun: nothing in the current code path warns the user that home-directory resolution failed and that credentials are landing somewhere unexpected.
Proposed Solution
Replace the silent PathBuf::from(".") fallback with one of:
- Preferred: treat an unresolved home directory as a hard error — return a
Result/propagate an error from get_config_dir() (and its callers) so the CLI exits with a clear, actionable message (e.g., "Could not determine home directory; set $HOME and retry") instead of silently proceeding with a working-directory-relative path.
- Minimum acceptable: if changing
get_config_dir()'s signature to return a Result is too invasive for this call site's current usages, at minimum print a loud, explicit warning to stderr every time the fallback path is used, so users are never surprised by where their credentials landed.
Alternatives considered: attempting to guess a "better" fallback location (e.g., /tmp or $XDG_CONFIG_HOME) — rejected as still implicit and potentially just as surprising; failing loudly (or erroring outright) is more honest and avoids compounding the credential-exposure risk with a different silent guess.
Technical Scope
src/utils/mod.rs: get_config_dir() (lines 56-65) — change fallback behavior from silent PathBuf::from(".") to a hard error or explicit stderr warning.
- Callers of
get_config_dir() (save_config, save_token, get_current_chain, save_current_chain, and any other function that resolves the config directory) — update to propagate/handle the new error path if the signature changes.
src/cli/handlers.rs (and main/entrypoint, wherever top-level error handling occurs) — ensure a clear, user-facing error message is surfaced if home-directory resolution fails, rather than a raw panic or silent continuation.
- Tests: a test simulating
dirs_next::home_dir() returning None (e.g., via a test-only injection point or by unsetting HOME in a controlled test environment) to confirm the CLI errors/warns instead of silently writing to the working directory.
Acceptance Criteria
Edge Cases
HOME set to an empty string vs. entirely unset — confirm dirs_next::home_dir()'s actual behavior in both cases and that both are handled the same way by the fix.
- Running inside a container with
HOME=/root but /root not writable — this is a different (permission) failure mode than an unresolved home directory and should produce a distinct, accurate error rather than being conflated with the "no home directory" case.
- Running inside a git-tracked directory when the fallback would otherwise trigger — the fix should prevent
./.txio/ from ever being created silently, directly closing the accidental-commit risk described above.
Risks
- If changed to a hard error, any existing (undocumented) workflows relying on the current working-directory fallback — however unintentional — will break. This is considered acceptable and is in fact the point of the fix, but should be called out in release notes.
- Low regression risk for the common case, since the fallback path only triggers when home-directory resolution already fails, which is by definition an unsupported/edge configuration today.
- No data migration needed.
Deliverables
- Updated
get_config_dir() (and callers) that hard-errors or loudly warns instead of silently falling back to the current working directory.
- Test coverage for the unresolved-home-directory path.
Labels
GrantFox OSS, Maybe Rewarded, Official Campaign | FWC26, Third Campaign, bug, good first issue, priority:low
Priority
Low — narrow environmental edge case, but the silent-fallback behavior is a real footgun given it affects where credentials land.
Estimated Completion: 96 hours
Telegram: https://t.me/txioCommunity
Summary
get_config_dir()silently falls back to the current working directory (./) when the user's home directory cannot be resolved, causing the CLI to create./.txio/— and store the auth token and config.json there — in whatever directory the command happens to be run from, with no warning to the user.Background
get_config_dir()insrc/utils/mod.rs(lines 56-65) callsdirs_next::home_dir()to locate the user's home directory, and falls back toPathBuf::from(".")when that call returnsNone.dirs_next::home_dir()returnsNonein several realistic environments: minimal containers without a populatedHOMEenv var or/etc/passwdentry, some CI runners, sandboxed/chrooted environments, or misconfigured shells.When this fallback triggers, the CLI silently creates
./.txio/— a directory relative to wherever the current process's working directory happens to be — instead of a true, stable home directory. This has two concrete consequences:~/.txio/. A CI job or container that gets torn down after each run would silently lose "persisted" credentials every time, defeating the purpose of persistence, without any error being surfaced.txiois run from inside a project directory (e.g., a developer testing the CLI from within a git-tracked repo), the fallback creates./.txio/inside that project. If the directory isn't already gitignored, the auth token and config file — potentially containing secrets — could end up staged or committed to a git repository, a significantly worse outcome than simply failing to persist state.This is a silent footgun: nothing in the current code path warns the user that home-directory resolution failed and that credentials are landing somewhere unexpected.
Proposed Solution
Replace the silent
PathBuf::from(".")fallback with one of:Result/propagate an error fromget_config_dir()(and its callers) so the CLI exits with a clear, actionable message (e.g., "Could not determine home directory; set $HOME and retry") instead of silently proceeding with a working-directory-relative path.get_config_dir()'s signature to return aResultis too invasive for this call site's current usages, at minimum print a loud, explicit warning to stderr every time the fallback path is used, so users are never surprised by where their credentials landed.Alternatives considered: attempting to guess a "better" fallback location (e.g.,
/tmpor$XDG_CONFIG_HOME) — rejected as still implicit and potentially just as surprising; failing loudly (or erroring outright) is more honest and avoids compounding the credential-exposure risk with a different silent guess.Technical Scope
src/utils/mod.rs:get_config_dir()(lines 56-65) — change fallback behavior from silentPathBuf::from(".")to a hard error or explicit stderr warning.get_config_dir()(save_config,save_token,get_current_chain,save_current_chain, and any other function that resolves the config directory) — update to propagate/handle the new error path if the signature changes.src/cli/handlers.rs(andmain/entrypoint, wherever top-level error handling occurs) — ensure a clear, user-facing error message is surfaced if home-directory resolution fails, rather than a raw panic or silent continuation.dirs_next::home_dir()returningNone(e.g., via a test-only injection point or by unsettingHOMEin a controlled test environment) to confirm the CLI errors/warns instead of silently writing to the working directory.Acceptance Criteria
dirs_next::home_dir()returnsNone, the CLI either exits with a clear error message, or (minimum) prints an unambiguous warning to stderr before proceeding — silent fallback to.is no longer possible.get_config_dir()compile and handle theResultappropriately (no.unwrap()-induced panics with unhelpful messages).Edge Cases
HOMEset to an empty string vs. entirely unset — confirmdirs_next::home_dir()'s actual behavior in both cases and that both are handled the same way by the fix.HOME=/rootbut/rootnot writable — this is a different (permission) failure mode than an unresolved home directory and should produce a distinct, accurate error rather than being conflated with the "no home directory" case../.txio/from ever being created silently, directly closing the accidental-commit risk described above.Risks
Deliverables
get_config_dir()(and callers) that hard-errors or loudly warns instead of silently falling back to the current working directory.Labels
GrantFox OSS, Maybe Rewarded, Official Campaign | FWC26, Third Campaign, bug, good first issue, priority:low
Priority
Low — narrow environmental edge case, but the silent-fallback behavior is a real footgun given it affects where credentials land.
Estimated Completion: 96 hours
Telegram: https://t.me/txioCommunity