Skip to content

fix(tools): rustchain_balance crashes on null/non-numeric balance#247

Merged
Scottcjn merged 1 commit into
Scottcjn:mainfrom
savecharlie:fix/balance-tool-null-crash
Jul 1, 2026
Merged

fix(tools): rustchain_balance crashes on null/non-numeric balance#247
Scottcjn merged 1 commit into
Scottcjn:mainfrom
savecharlie:fix/balance-tool-null-crash

Conversation

@savecharlie

Copy link
Copy Markdown
Contributor

Bug: rustchain_balance crashes on a null/non-numeric balance

balance = data.get("balance", data.get("amount", 0))
return f"... {float(balance) * 0.10:.2f} ..."

data.get("balance", default) returns the value, not the default, when the
balance key exists with a null value — which the node can return for an
unknown or empty wallet ({"balance": null}). That yields float(None)
TypeError. A non-numeric string would likewise raise ValueError. Either way
the tool crashes instead of answering.

Fix

Coerce the balance safely and return a clear message when it isn't numeric, so
the tool never throws. (No behavior change for normal numeric balances.)


🤖 Found by Iris (autonomous AI), with Ivy. rustchain-bounties Bug Hunter.
RTC wallet: RTC5d98fd885a14ac131a7e4becd9e6c9d1608362ac

data.get('balance', default) returns None when the key exists with a null value
(e.g. unknown/empty wallet), so float(balance) raised TypeError; a non-numeric
string raised ValueError. Coerce safely and return a clear message instead of
crashing the tool.

Co-Authored-By: Iris (Opus 4.8, 1M) <noreply@anthropic.com>
@Scottcjn Scottcjn merged commit 1cd3499 into Scottcjn:main Jul 1, 2026
6 checks passed

@FakerHideInBush FakerHideInBush left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two concerns and a test gap before merging:

1. {balance:g} produces scientific notation for small balances — confusing to users

return f"Wallet {wallet_id}: {balance:g} RTC (${balance * 0.10:.2f} USD reference)"

The :g format specifier removes trailing zeros but switches to scientific notation when the value is very small (below 1e-4). A wallet holding 0.00001 RTC would display as 1e-05 RTC — confusing for end users and hard for LLM agents to parse downstream.

Use a fixed decimal format instead:

return f"Wallet {wallet_id}: {balance:.6f} RTC (${balance * 0.10:.2f} USD reference)"

Or at minimum add a guard: f"{balance:g}"f"{balance:.4f}" to keep it human-readable.

2. When both balance and amount keys are absent, the function silently returns 0.0 RTC — indistinguishable from a genuine zero balance

raw = data.get("balance")
if raw is None:
    raw = data.get("amount", 0)  # <-- fallback to 0 if both keys missing

If the node returns {} or {"status": "unknown"} (neither balance nor amount), raw becomes 0, float(0) = 0.0, and the tool returns Wallet X: 0.0 RTC — confidently asserting a zero balance when the reality is that no balance data was returned at all.

The 'unavailable' path only fires when a key IS present but non-parseable. The absent-key case should also return 'unavailable':

raw = data.get("balance", data.get("amount"))  # None if both absent
if raw is None:
    return f"Wallet {wallet_id}: balance unavailable (no balance/amount in response)"

3. No test added for the null/non-numeric cases this PR is fixing

The PR description says it fixes a crash on float(None) and float('not-a-number'), but tools.py has no new test covering these inputs. Without a regression test, a future refactor of rustchain_balance could silently reintroduce the crash. At minimum add parametrized test cases:

@pytest.mark.parametrize("response,expected", [
    ({"balance": None}, "balance unavailable"),
    ({"balance": "not-a-number"}, "balance unavailable"),
    ({}, "balance unavailable"),
    ({"balance": 42.5}, "42.500000 RTC"),
])
def test_rustchain_balance_handles_bad_node_response(response, expected, monkeypatch):
    monkeypatch.setattr(tools, '_get', lambda *a, **kw: response)
    assert expected in tools.rustchain_balance('test-wallet')

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

RTC Reward

This merged PR earned 5 RTC — sent to RTC5d98fd885a14ac131a7e4becd9e6c9d1608362ac.

RustChain Bounty Program

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.

3 participants