Skip to content

CP-14339 - Guard against a missing area page in result attachment generation#77

Merged
spaulsandhu merged 2 commits into
mainfrom
CP-14339-guard-nil-area-page
Jul 9, 2026
Merged

CP-14339 - Guard against a missing area page in result attachment generation#77
spaulsandhu merged 2 commits into
mainfrom
CP-14339-guard-nil-area-page

Conversation

@spaulsandhu

@spaulsandhu spaulsandhu commented Jul 8, 2026

Copy link
Copy Markdown
Member

Overview

This fixes the Airbrake undefined method '<' for nil on GET /api/submissions/:id (CP-14339). Result-attachment generation 500s whenever a template field area has no page.

page is a permitted-but-not-required area param (templates_controller.rb lists it alongside x/y/w/h, not required), so an imported, copied, or API-built area can legitimately omit it. When it does, pdf.pages[area['page']] in Submissions::GenerateResultAttachments.fill_submitter_fields passes nil into HexaPDF, whose PageTreeNode#page does index = self[:Count] + index if index < 0 and blows up on nil < 0 (page_tree_node.rb:96). The existing next if page.nil? guard is one line too late, the exception fires inside the pages[...] call before it runs. This is the only .pages[<variable>] indexing site in the codebase, so it's the only place with this crash.

The guard skips the area (mirroring the surrounding next if pdf.nil? style) and logs a warning on the way out, since this is a signed-document product and silently dropping a field without a trace is worse than the crash. A malformed template stays visible in the logs instead.

Added spec/lib/submissions/generate_result_attachments_spec.rb covering a missing page key, an explicit page: nil, and an out-of-range page (confirming the existing nil-page-result handling still applies and the new guard only catches nil).

Not in scope here: why the affected submission's template has a nil page in the first place. Could be a one-off import artifact or a data-integrity gap worth a backfill, but that's a separate slice from the crash guard.

🤖 Generated with Claude Code

The issue here is result-attachment generation 500s with `undefined method
'<' for nil` whenever a template field area has no `page`. It's a
permitted-but-not-required area param, so an imported or API-built area can
omit it, and `pdf.pages[nil]` walks straight into HexaPDF's `nil < 0` at
page_tree_node.rb:96. The existing `next if page.nil?` guard runs one line too
late: the exception fires inside the `pages[...]` call itself.

This adds a nil-guard before the index and skips the area, mirroring the
surrounding `next if pdf.nil?` style. It logs a warning on the way out so a
genuinely malformed template doesn't silently drop a field from a signed
document without a trace. Adds a spec for the missing / nil / out-of-range
page cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# HexaPDF's pages[nil] does `nil < 0` and raises. `page` is a
# permitted-but-not-required area param, so a malformed/imported area
# can omit it. Skip it, but log so silently-incomplete signed docs stay visible.
if area['page'].nil?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think this is reasonable for now, if anyone complains about missing pages we can check logs and whatnot, but crashing completely isn't really acceptable lol

rubocop flags the set_ prefix as a writer-method name; assign_field_area
reads fine and isn't mistaken for an accessor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@jewls618 jewls618 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.

Test coverage looks good 👍🏼

@spaulsandhu spaulsandhu merged commit 8eeec92 into main Jul 9, 2026
5 checks passed
@spaulsandhu spaulsandhu deleted the CP-14339-guard-nil-area-page branch July 9, 2026 13:56
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.

2 participants