Skip to content

Fix contract extend panic when extending a missing entry - #2657

Merged
fnando merged 2 commits into
mainfrom
extend-no-op-panic
Jul 27, 2026
Merged

Fix contract extend panic when extending a missing entry#2657
fnando merged 2 commits into
mainfrom
extend-no-op-panic

Conversation

@fnando

@fnando fnando commented Jul 27, 2026

Copy link
Copy Markdown
Member

What

Fixes a panic in stellar contract extend. When run against a well-formed but non-existent contract entry, the transaction goes through as a no-op and the CLI then crashes with index out of bounds: the len is 0 but the index is 0. It now exits cleanly with a "Ledger entry not found" error instead.

Why

On a no-op extend the code fetched the ledger entries and unconditionally indexed entry.entries[0]. For a non-existent entry that vec is empty, so the index panicked. This replaces the raw index with .first().ok_or(Error::LedgerEntryNotFound)?, reusing the existing error variant already returned for the analogous no-op cases in the same function. Fixes #2599.

Known limitations

N/A

Copilot AI review requested due to automatic review settings July 27, 2026 16:36
@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX Jul 27, 2026
@fnando fnando self-assigned this Jul 27, 2026
@fnando fnando moved this from Backlog (Not Ready) to Needs Review in DevX Jul 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Prevents contract extend from panicking when the target ledger entry is missing.

Changes:

  • Safely handles empty ledger-entry responses.
  • Adds integration coverage for the regression.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
cmd/soroban-cli/src/commands/contract/extend.rs Returns LedgerEntryNotFound instead of indexing an empty vector.
cmd/crates/soroban-test/tests/it/integration/hello_world.rs Verifies a missing entry produces a clean error without panic output.

@mootz12 mootz12 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good catch

@fnando
fnando enabled auto-merge (squash) July 27, 2026 17:11
@fnando
fnando merged commit ac1379f into main Jul 27, 2026
229 checks passed
@fnando
fnando deleted the extend-no-op-panic branch July 27, 2026 17:26
@github-project-automation github-project-automation Bot moved this from Needs Review to Done in DevX Jul 27, 2026
leighmcculloch added a commit that referenced this pull request Jul 28, 2026
### What

Guard `stellar contract restore` against the same "index out of bounds"
panic that #2657 fixed in `extend`: the no-op path unconditionally
indexed `entry.entries[0]`, which panics if the post-transaction fetch
returns no entries. It now errors with "Ledger entry not found" instead.

### Why

`restore` carried the identical unguarded indexing as `extend` (see
#2599), so this applies the same
`.first().ok_or(Error::LedgerEntryNotFound)?` fix. Unlike extend,
restoring a non-existent entry fails cleanly at simulation ("Missing
entry to restore") before reaching the no-op path, so this guard is
defensive hardening for the narrower case where the fetch after a no-op
comes back empty (e.g. the entry was evicted in the meantime). The
regression test asserts the non-existent-entry case fails cleanly at
simulation without panicking.

### Known limitations

The empty-fetch-after-no-op case itself isn't covered by an integration
test since simulation catches the straightforward missing-entry scenario
first.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

stellar contract extend panics with "index out of bounds" when the extension is a no-op

3 participants