Skip to content

Reject empty fields map in AI Translation.translate_fields/6 - #558

Merged
ddon merged 2 commits into
BeamLabEU:devfrom
mdon:ai-translation-empty-fields-guard
May 21, 2026
Merged

Reject empty fields map in AI Translation.translate_fields/6#558
ddon merged 2 commits into
BeamLabEU:devfrom
mdon:ai-translation-empty-fields-guard

Conversation

@mdon

@mdonmdon commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to PR #557 — boss's CLAUDE_REVIEW left this NITPICK as my call.

Translation.translate_fields/6 previously accepted an empty fields map (is_map/1 + validate_unique_markers([]) both pass), then rendered a prompt with no field variables, called PhoenixKitAI.ask_with_prompt/4 (real token spend), and only failed downstream in parse_response/2 with {:parse_error, :no_markers}.

This adds a validate_non_empty/1 guard before the unique-markers check so an empty fields map is rejected up front. Same {:error, {:parse_error, :no_markers}} sentinel as the downstream parser — callers don't have to branch on a new error class.

Test plan

  • New test "empty fields map → :no_markers (rejected before plugin call)" in translation_test.exs
  • All 17 existing translation tests still pass
  • mix format clean
  • mix credo --strict clean

Diff size

+23 / -0 across lib/modules/ai/translation.ex and the matching test file.

mdon added 2 commits May 21, 2026 06:56
PR BeamLabEU#557 follow-up — boss left this NITPICK as my call. An empty
`fields` map passed to `translate_fields/6` passed `is_map/1` and
`validate_unique_markers([])`, then rendered a prompt with no
field variables, called `PhoenixKitAI.ask_with_prompt/4` (real
token spend), and only failed downstream in `parse_response/2`
with `{:parse_error, :no_markers}`. Reject up front so a caller
bug doesn't burn a request.
Returns `{:error, {:parse_error, :no_markers}}` — same sentinel
the downstream parser returns, so callers don't have to branch on
a new error class.
Phase 2 triage on PR BeamLabEU#558 caught the describe block's validation
order list still claimed `endpoint → prompt → unique-markers →
plugin-available` after the new `validate_non_empty` step was
added in between. Update to match the actual chain so anyone
reading the test contract gets the right order.
@ddon
ddon merged commit 0523c7a into BeamLabEU:devMay 21, 2026
ddon pushed a commit that referenced this pull request May 21, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ddon pushed a commit that referenced this pull request May 25, 2026
BUG-HIGH (dialyzer failure on ask_with_prompt/4) fixed pre-existing
via .dialyzer_ignore.exs entry. Two NITPICKs (doc example re-enqueue
phrasing, regex /i flag) fixed in post-merge commits. Two items N/A
(completed-key doc trimmed; empty-fields-guard was scope of PR #558).
ddon pushed a commit that referenced this pull request May 25, 2026
Core fix (validate_non_empty/1 guard) was the scope of this PR and
shipped. One NITPICK on the error category atom (:parse_error vs a
dedicated :empty_fields) documented as Skipped — the review accepted
the sentinel reuse to avoid forcing callers to handle a second arm
with no behavioural difference.
ddon pushed a commit that referenced this pull request May 25, 2026
Release rollup since 1.7.120:
- PR #568: native <dialog> modal (PkDialog), core list-UI toolkit
(BulkSelect, Sortable, ReorderModal, load_more), race-free sort_selector
- PR #568 post-merge review fixes (untranslated reorder label, named group/row)
- PR #569: PhoenixKit.boot/1 hook, locale-aware Activity dates, broad i18n sweep
- PR #550/#552/#554/#557/#558/#559 follow-ups
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@mdon@ddon