Skip to content

Fix InvalidLoad for struct calculations without arguments#53

Closed
cinoss wants to merge 3 commits intoash-project:mainfrom
cinoss:fix-calculation-complex-load
Closed

Fix InvalidLoad for struct calculations without arguments#53
cinoss wants to merge 3 commits intoash-project:mainfrom
cinoss:fix-calculation-complex-load

Conversation

@cinoss
Copy link
Copy Markdown

@cinoss cinoss commented Feb 21, 2026

Summary

Fixes an issue where struct/embedded resource calculations without arguments couldn't be requested via RPC — neither as simple fields nor with field selection.

The field_selector.ex classified these as :calculation_complex and:

  • Simple atom request (e.g., "summary") → rejected with requires_field_selection
  • Field selection (e.g., {summary: ["viewCount"]}) → built a nested load spec {:summary, [:view_count]} that Ash doesn't support for calculations, causing InvalidLoad

Calculations with arguments worked fine because they go through :calculation_with_args, a different code path.

Fix

For :calculation_complex without arguments:

  1. Allow simple atom selection (load flat, return all sub-fields)
  2. For field selection, load the calculation flat and let the response template handle sub-field extraction — same pattern already used for aggregates

Changes

  • lib/ash_typescript/rpc/field_processing/field_selector.ex — Handle :calculation_complex in both process_simple_resource_field and process_nested_resource_field
  • Updated unit tests and integration test to assert success instead of failure

Test plan

  • All 1796 existing tests pass (0 failures)
  • Simple atom selection works: ["summary"] → loads flat, returns all sub-fields
  • Field selection works: {summary: ["viewCount"]} → loads flat, template extracts sub-fields
  • Nested field selection works: {summary: [{performanceMetrics: ["focusTimeSeconds"]}]}
  • Calculations with arguments still work as before

🤖 Generated with Claude Code

cinoss and others added 2 commits February 21, 2026 18:11
Struct calculations (`:calculation_complex`) without arguments fail with
`Ash.Error.Query.InvalidLoad` when requested via RPC. The field selector
builds a nested load spec like `{:calc_name, [:field1, :field2]}`, but
Ash only supports nested loads on relationships — not on calculations.

This changes `:calculation_complex` handling in two places:

1. `process_nested_resource_field`: load the calculation flat (just the
   atom name) instead of building nested load specs. The extraction
   template still tracks sub-fields for response formatting. This
   matches how aggregates are already handled.

2. `process_simple_resource_field`: allow `:calculation_complex` as a
   simple field request, loading it flat and returning all sub-fields.

Calculations with arguments (`:calculation_with_args`) are unaffected —
they go through `process_calculation_with_args` which correctly passes
args via `{:calc_name, {args, fields}}`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests now assert success instead of failure for :calculation_complex
fields without arguments, matching the fix in field_selector.ex that
loads these calculations flat and delegates sub-field extraction to
the response template.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
{select, load ++ [load_spec], template ++ [{internal_name, nested_template}]}

:calculation_complex ->
# Ash doesn't support nested loads on calculations (only on relationships).
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.

Ash does support that, it just needs to be specified as calculation: {[arg: :val], [load: :through]}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@zachdaniel I have made some change, can you plz have a look?

…ources, bare atom for TypedStruct

Ash's load_through only works for calculations returning Ash Resources (which
support queries). TypedStruct/typed map calculations must load as bare atoms —
sub-field extraction is handled by the extraction template.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Torkan
Copy link
Copy Markdown
Collaborator

Torkan commented Mar 28, 2026

Sorry for taking so long to jump on this one 😅

I have now fixed this issue in main, ash_typescript now properly detects if a calculation returns a resource or embedded resource, and builds the correct load statements when constructing the underlying Ash.Query.

Please note that for all complex fields that are in some way typed, ash_typescript always requires the caller to specify which fields they want back, so requesting a complex field just by its field name still won't work.

Hoping to put out a new release before the week is done with this fix and some other updates 😄

@Torkan Torkan closed this Mar 28, 2026
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