Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

nested Timepoint/Duration in struct args rejected by from_json

Open Beginner friendly
#2,753 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
rust
Domain
cli

Research direction

The issue is in cmd/crates/soroban-spec-tools/src/lib.rs. Look at the from_json function around line 328 and the from_json_primitives function around line 937. The fix involves adding ScType::Timepoint and ScType::Duration to the match arm routing to primitives, and then ensuring they produce the correct ScVal variant (ScVal::Timepoint and ScVal::Duration) instead of ScVal::U64. Test by building the CLI and running the provided reproduction command.

Written by the indexing model from the issue text.

Description

Problem

When a contract function takes a struct with a `Timepoint` or `Duration` field, `stellar contract invoke` fails to parse the JSON argument. Top-level Timepoint/Duration args work fine.

Root cause

Two bugs in `cmd/crates/soroban-spec-tools/src/lib.rs`:

1. `from_json` does not route Timepoint/Duration to primitive parsing

The match arm at line ~328 that dispatches to `from_json_primitives` lists:
`Bool, U128, I128, U256, I256, I32, I64, U32, U64, String, Symbol, Address, MuxedAddress, Bytes, BytesN`

`Timepoint` and `Duration` are missing. When a struct field has type `Timepoint`, `parse_strukt` calls `from_json(Value::Number(1234), ScType::Timepoint)`. Since Timepoint is not in the list, it falls through to the serde catch-all which tries to deserialize a bare JSON number as `ScVal` -- this fails because `ScVal` expects tagged format (`{"timepoint": 1234}`).

Top-level args work because `from_string` pre-wraps the value as `{"timepoint": "value"}` before calling `from_json`.

2. `from_json_primitives` constructs `ScVal::U64` instead of `ScVal::Timepoint`

Line ~937:
```rust
(ScType::U64 | ScType::Timepoint | ScType::Duration, Value::Number(n)) => ScVal::U64(...)
```

This produces `ScVal::U64` for all three types. The Soroban VM distinguishes `SCV_U64` from `SCV_TIMEPOINT` and `SCV_DURATION` -- passing the wrong discriminant causes a host argument type mismatch at runtime.

Reproduce

Contract:
```rust
#[contracttype]
pub struct TimedAction {
pub deadline: Timepoint,
pub name: Symbol,
}

pub fn schedule(env: Env, action: TimedAction) -> TimedAction { action }
```

Invoke:
```
stellar contract invoke --id -- schedule --action '{"deadline": 1760501234, "name": "test"}'
```

Fails with a serde deserialization error on the `deadline` field.

Fix
  1. Add `| ScType::Timepoint | ScType::Duration` to the `from_json` primitives routing arm
  2. Split the `from_json_primitives` match so Timepoint produces `ScVal::Timepoint(TimePoint(...))` and Duration produces `ScVal::Duration(Duration(...))`
Dominant language
Rust
Stars
123
Forks
147
Avg merge
3d 11h
Merged PRs (30d)
39

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stellar/stellar-cli

All issues in stellar/stellar-cli

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.