Skip to content

πŸ› fix: Blame a failure a boxed body returns on the line that failed - #164

Merged
135yshr merged 1 commit into
mainfrom
claude/next-work-tasks-5b56lt
Sep 27, 2026
Merged

135yshr merged 1 commit into
mainfrom
claude/next-work-tasks-5b56lt

Conversation

@135yshr

@135yshr 135yshr commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Overview

Closes #163

A failure inside a lambda was reported, by the compiled program, at the line that called the lambda. A lambda passed to lick was blamed on the whole call:

nyan xs = [1, 2]
nya(lick(xs, paw(x) {
  bring to_float("bad")
}))
prog.nyan:2:1: Hiss! Cannot read "bad" as a Float, nya~   # before, compiled
prog.nyan:3:3: Hiss! Cannot read "bad" as a Float, nya~   # after, and the playground always

Why

The generated body already recorded the failing line. It then handed its result back through meow.Returning(__caller, v), which always put the program back at the caller's position. Its doc comment assumed "a call that fails never reaches it". That holds where a failure panics (a typed function). A boxed body, though, hands its failure back as a value, an unhandled Furball, and that goes through Returning like any result. So it was not only lambdas: any function whose result is boxed, such as meow f() P returning a kitty, had its failure moved onto the calling line.

The change

Returning now follows the rule meow.Call already keeps: it goes back to the caller only when the value is not an unhandled Furball. The change is one runtime function. No generated code changes, so no golden moves.

A lambda that succeeds, or one that caught its own failure with ~>, still leaves the program at the call site. A failure later in the same statement is still blamed on that statement, and both cases are pinned.

Verification

  • go test ./... passes
  • go vet ./... passes
  • Golden files updated if needed: none moved
  • New compiler/lambda_position_test.go runs 7 programs on both the compiled binary and the interpreter. It requires the same output and the same failure, position included. Cases: a lambda called by name, a lambda passed to lick, the last line of a longer lambda, a lambda called inside a typed function, a named function returning a kitty, a failure after a lambda that succeeded, and a failure after a lambda that caught its own. The five failure cases fail on the compiled side without the fix; the two success cases pass either way.
  • New runtime/meowrt/position_test.go unit tests for Returning: it goes back to the caller for a boxed and for a native result, stays put for an unhandled Furball, and goes back for a caught one. The Furball case fails without the fix.
  • WASM playground builds. gofmt -l is clean, and staticcheck, gocritic and misspell are clean on the changed files.
  • The e2e examples (hello, fibonacci, fizzbuzz, list_ops) run

Impact

  • Compiler (lexer / parser / checker / codegen)
  • Runtime (meowrt / file / http): Returning in runtime/meowrt/position.go
  • CLI
  • Documentation
  • Playground: unchanged, it already reported the line that failed

A meow binary run outside this checkout builds against the published runtime module, so it picks this up with the next release that carries the runtime, as it did for Seed in #159.

AI Session

Checklist

  • I have read the CONTRIBUTING guide
  • My changes follow the project's coding style
  • I have added/updated tests for my changes
  • Commit messages use gitmoji prefix

πŸ€– Generated with Claude Code

https://claude.ai/code/session_01Scc7p1RecmFoikhcXwnTMu


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Failures inside lambdas are now reported at the line where they occur, rather than at the caller’s line.
    • When a lambda handles its own failure, execution resumes with the caller’s position correctly restored.

A failure inside a lambda was reported, by the compiled program, at the
line that called it: a lambda passed to lick was blamed on the whole call.
The body did record the failing line, but it handed its result back
through meow.Returning, which always put the program back at the
caller's position. That only holds where a failure panics; a boxed body
hands its failure back as a value, so any lambda, and any function whose
result is boxed, had its failure moved onto the calling line. The
playground reported the line that failed.

Returning now follows the rule meow.Call already keeps: it goes back to
the caller only when the value is not an unhandled Furball.

Closes #163

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Scc7p1RecmFoikhcXwnTMu
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
πŸ“ Code Review βœ… Completed 2026-09-27T09:32:12.430317Z 6791115 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with πŸ‘€ while any review is running, comments if it has suggestions, and reacts with πŸ‘ once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack β†’

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: fe0cf4d8-322c-45c3-ae02-3bc8ff3119d4

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between f466aba and 6791115.

πŸ“’ Files selected for processing (3)
  • compiler/lambda_position_test.go
  • runtime/meowrt/position.go
  • runtime/meowrt/position_test.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


πŸ“ Walkthrough

Walkthrough

Returning now preserves the failure position when it receives an unhandled boxed Furball. Tests cover runtime behavior and compiled and interpreted lambda failures.

Changes

Failure Position Handling

Layer / File(s) Summary
Preserve positions for boxed failures
runtime/meowrt/position.go, runtime/meowrt/position_test.go, compiler/lambda_position_test.go
Returning does not restore the caller position for a boxed unhandled Furball. Runtime tests check failure and return positions. Compiler tests check expected output and failure text across compiled and interpreted cases.

Priority: βž– Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix Β· Severity of issue fixed: Medium

Merge Risk: βšͺ Minimal Β· up to 67911

No actionable issue remains; the change is mergeable after normal checks.

Security Architecture Review

Security architecture risk: πŸ”΅ Low Β· up to 67911

Failures returned from boxed function bodies are now reported at the failing line rather than the calling line. The change does not appear to expand access or privileges, but its effect on shared diagnostic state warrants a design-level check.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred β€” The demonstrated exposure is the location included in failure diagnostics from generated returns, not an expanded privilege or data-access path.

Trust Boundaries and Controls

  • observed β€” The existing AsFurball classifier distinguishes unhandled failures from handled failures and other values before Returning changes diagnostic position.
πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Title check βœ… Passed The title clearly identifies the main change: preserving the failure position for failures returned by boxed bodies. It is concise and specific.
Description check βœ… Passed The description follows the required template and explains the problem, cause, implementation, verification, impact, tests, and AI session. The Entire-Checkpoint field is not included, but the descrip…
Linked Issues check βœ… Passed The changes satisfy issue #163. runtime/meowrt/position.go now preserves the failure position when Returning receives an unhandled Furball. Other results restore the caller position. The new run…
Out of Scope Changes check βœ… Passed The changes remain within issue #163. The runtime change implements the position rule, and the added runtime and compiler tests verify that rule across the reported cases. No unrelated production beha…
Docstring Coverage βœ… Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 3 files.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Commit to this branch
  • Create a new PR
πŸ§ͺ Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

A rabbit checks the caller’s place,
Then keeps the spot where failures trace.
Boxed Furballs mark the failing line,
While successful calls return in time.
Compiled and interpreted tests agree,
The rabbit hops off, pleased to see.

Comment @coderabbitai help to get the list of available commands.

@135yshr 135yshr self-assigned this Sep 27, 2026
@135yshr
135yshr merged commit 38a0651 into main Sep 27, 2026
4 checks passed
@135yshr
135yshr deleted the claude/next-work-tasks-5b56lt branch September 27, 2026 09:31

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6791115437

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +52 to +53
if _, failed := AsFurball(value); failed {
return v

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore the caller position when a returned failure is caught

When the caller catches this Furball with ~>, GagOr turns the call into a successful value but never restores here, so any later failure in the same statement is blamed on the callee. For example, if g fails on line 2, nya(g() ~> 0.0, to_float("x")) on line 4 now reports the to_float("x") failure at line 2; before this change the compiled backend correctly reported line 4. The recovery path needs to restore the position captured before evaluating the caught expression.

Useful? React with πŸ‘Β / πŸ‘Ž.

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.

A failure a lambda or boxed function returns is blamed on the caller's line

2 participants