Skip to content

feat(LAB-4614): return a clear error when isUsedForConsensus is refused - #2062

Draft
RuellePaul wants to merge 1 commit into
mainfrom
feature/lab-4614-aau-i-get-the-right-error-message-when-using
Draft

feat(LAB-4614): return a clear error when isUsedForConsensus is refused#2062
RuellePaul wants to merge 1 commit into
mainfrom
feature/lab-4614-aau-i-get-the-right-error-message-when-using

Conversation

@RuellePaul

Copy link
Copy Markdown
Contributor

Purpose: Translate the backend's new deprecation error into a typed SDK exception, so the user sees an actionable message instead of a TransportQueryError wrapping a JS stack trace.

Paired MR: kili !14392. Ships in either order — against a pre-deploy backend the token is simply absent and the user sees today's error. Graceful degradation.

Plan document: https://linear.app/kili-technology/document/lab-4614-aau-i-get-the-right-error-message-when-using-kiliupdate-ce9688058bc8


Approach: pass through, do NOT reject client-side

Five reasons, all verified rather than assumed:

  1. project_id is optional on update_properties_in_assets — a client-side check would need up to two extra round trips on every call using the argument.
  2. asset_ids can span multiple projects, which may mix workflow v1 and v2. A single client-side verdict cannot express that; the backend evaluates per project.
  3. A client-side check races migration — workflow version is backend state and can flip between check and mutation.
  4. Pass-through fails fast: the tenacity predicate is retry_all(...) whose final conjunct matches none of this message, so there is no retry and stop_after_delay(3*60) never engages. One round trip, immediate raise.
  5. Zero regression for workflow v1 — the call goes through byte-identical to today.

⚠️ The most important thing in this diff is what it does NOT change

src/kili/entrypoints/mutations/asset/helpers.py is untouched — verified explicitly: git diff origin/main -- helpers.py is empty. "isUsedForConsensus": is_used_for_consensus_array is still at line 51 and still forwarded.

An earlier draft of this change stripped that parameter and its mapping. That would have silently disabled consensus for every workflow-v1 user, with no error at all — the field is still valid and still honoured on v1. The regression guard is a test asserting isUsedForConsensus is present in the dataArray sent on the v1 happy path.

Acceptance criterion — verified end to end, not inferred

Ran the real path with the literal backend string. The user sees exactly:

isUsedForConsensus is deprecated in update_properties_in_assets. Use update_asset_consensus instead to manage consensus for this asset.

Byte-identical to the AC. __cause__ renders GraphQL error at index 0: [isUsedForConsensusDeprecated] … — the "at index 0" proves the test exercises the real mutate_from_paginated_call re-wrap rather than a synthetic error. The exception is a ValueError subclass, so existing except ValueError handlers keep working.

Contract compliance

Matches on the literal substring [isUsedForConsensusDeprecated], scanning every element of the errors array — necessary because GraphQLError.__init__ only ever reads error[0]. extensions.code is ignored entirely (it is the generic OPERATION_RESOLUTION_FAILURE). The prose after the token is not matched, so backend copy edits cannot break the SDK. Both true and false are covered.

Scoping note: the guard fires on workflowVersion >= 2v2 and v3 (v3 is "multi-step labeling", also multi-review). The acceptance message reads as an unconditional deprecation but is not one: the parameter still works on v1, and update_asset_consensus explicitly rejects v1. Release notes should say "on multi-review projects (workflow v2+)".

Documentation fixes

The backend confirmed new projects default to workflow v2 on every path the repo controls. So a reader following the published set_up_workflows tutorial today creates a v2 project and hits this exact error. The executable cell is swapped to update_asset_consensus rather than merely annotated, while stating that the correct setter depends on the project's workflow version — an on-prem instance with FLAG_MULTI_STEP_REVIEW=false still gets v1. The .md is regenerated by the repo hook, not hand-edited.

update_asset_consensus and kili.assets.update_consensus now document their workflow-v1 incompatibility, which neither mentioned before — a second documentation gap this ticket exposed.

Post-review fixes (agent self-review)

  • [REQUIRED] pylint 10.00 → 9.93: adding a Raises: section activated missing-raises-doc → documented MissingArgumentError and GraphQLError too.
  • [REQUIRED] presentation/client/asset.py went 999 → 1002 lines, tripping too-many-lines. Confirmed a regression rather than pre-existing by running pylint against the pristine origin/main copy (10.00/10) → fixed with the established # pylint: disable=too-many-lines convention, already used by 6 modules including sibling client/label.py.
  • [REQUIRED] The Raises: line for MissingArgumentError was factually wrong — written as "if both are provided", but it is also raised when neither is → corrected.
  • [REQUIRED] The _has_error_key generator expression sat exactly on the 100-char boundary where the local ruff 0.15.14 and the repo-pinned 0.1.15 could disagree — CI would break whichever way it was written → rewritten as an explicit loop so no formatter has a choice.
  • [SUGGESTION, considered and REJECTED] Gating the conversion on is_used_for_consensus_array is not None as well as the token — rejected because the backend only emits the token when the field is in the payload, so it guards an unreachable state.

Test honesty: tests 2 and 3 pass against pre-change code by design — they are regression guards, not new-behaviour tests. Test 1 is the only one that fails without the fix, and it does fail without it.

Verification

Baseline captured from a pristine tree before the first edit: 748 passed / pyright 0 / pylint 10.00. After: 751 passed — exactly +3, no regressions. pylint 10.00 restored, pyright 0, ruff set-comparison shows zero new findings. Full pre-commit suite passed at commit time including the repo-pinned ruff 0.1.15.

⚠️ Not run

  • tests/e2e/ — needs a live Kili instance and API key. CI runs unit+integration only, which is exactly what was run. No e2e test references is_used_for_consensus_array, but that is not proof.
  • Repo-wide ruff check reports 4119 findings on the implementing host — purely the 0.15.14 vs pinned 0.1.15 version gap, present on pristine origin/main too.

🤖 Planned and implemented by Claude Code.

The backend rejects `isUsedForConsensus` in `updatePropertiesInAssets` on
multi-review projects with an opaque `[unexpectedServiceError]` wrapped in a
GraphQL transport error. It now emits a domain error tagged
`[isUsedForConsensusDeprecated]`, which the SDK translates into a
`DeprecatedArgumentError` pointing at `update_asset_consensus`.

The argument is not rejected client-side: it still works on workflow v1
projects, where `update_asset_consensus` is not available. The field is still
sent and the error is only reinterpreted when the backend refuses it.

Also documents that `update_asset_consensus` is not compatible with workflow
v1, and updates the consensus tutorial to show both methods.
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@RuellePaul RuellePaul changed the title [Claude] LAB-4614: AAU, I get the right error message when using kili.update_properties_in_asset feat(LAB-4614): return a clear error when isUsedForConsensus is refused Aug 20, 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.

2 participants