Skip to content

fix(workflows): route unlisted tasks through unknown parameter/output types#2606

Open
JustAnotherNormalDev wants to merge 29 commits into
masterfrom
fix/workflows-functionapp-task-type
Open

fix(workflows): route unlisted tasks through unknown parameter/output types#2606
JustAnotherNormalDev wants to merge 29 commits into
masterfrom
fix/workflows-functionapp-task-type

Conversation

@JustAnotherNormalDev
Copy link
Copy Markdown
Contributor

@JustAnotherNormalDev JustAnotherNormalDev commented May 6, 2026

Problem

Listing workflow versions and loading executions could fail when the API returns task types that are not first-class in the SDK (for example new or beta task kinds in responses).

Solution

Route unlisted task types through UnknownWorkflowTaskParameters and UnknownWorkflowTaskOutput so the wire JSON is preserved and load no longer throws. Keep known task types on their existing dedicated classes.

UnknownWorkflowTaskParameters is constructed from the task type / taskType plus the parameters / input blob (not the full task envelope), so WorkflowTask.dump() stays aligned with the API shape.

For generic CogniteResource JSON/YAML round-trips, dump() must always yield a top-level dict. When _parameters is not a dict (for example a string from the fake resource generator in unit tests), dump() wraps the value in a single-key dict using _OPAQUE_WRAPPER_KEY ("cogniteSdkUnknownWorkflowTaskParametersOpaque"). That satisfies CogniteResource.load → load_resource_to_dict, which only accepts parsed JSON/YAML that resolves to a dict. _load detects that exact one-key shape and unwraps the inner value so the in-memory payload matches what was stored before serialization. Normal API dict payloads are returned unchanged and never use this wrapper.

Files

cognite/client/data_classes/workflows.py — unknown task parameters/output handling, load_parameters wiring, _OPAQUE_WRAPPER_KEY wrap/unwrap for non-dict unknown parameter bodies.
cognite/client/data_classes/init.py — export surface for updated workflow types.
tests/tests_unit/test_data_classes/test_workflows.py — coverage for unknown task serialization and related behavior.
tests/tests_unit/test_base.py — UnknownWorkflowTaskParameters included in generic CogniteResource round-trip tests where applicable.
cognite/client/_cognite_client.py — generated/synced client updates.
cognite/client/_sync_cognite_client.py — generated/synced sync client updates.
scripts/sync_client_codegen/sync_client_template.txt — codegen template updates matching generated client changes.

Parse functionApp parameters and execution output as first-class types.
Route unrecognized task types through Unknown parameters/output so listing
workflow versions no longer fails when the API adds new task kinds.

Co-authored-by: Cursor <cursoragent@cursor.com>
@JustAnotherNormalDev JustAnotherNormalDev requested review from a team as code owners May 6, 2026 10:29
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for the functionApp task type and adds UnknownWorkflowTaskParameters and UnknownWorkflowTaskOutput classes to handle unrecognized task types gracefully. Feedback was provided to improve the robustness of these new classes by handling non-dictionary data in their dump methods and ensuring consistent task_type tracking.

Comment thread cognite/client/data_classes/workflows.py Outdated
Comment thread cognite/client/data_classes/workflows.py Outdated
JustAnotherNormalDev and others added 3 commits May 6, 2026 16:18
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…-dict output

Co-authored-by: Cursor <cursoragent@cursor.com>
…omplete normalize

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 94.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.02%. Comparing base (4b38aa0) to head (63ad6ab).

Files with missing lines Patch % Lines
cognite/client/data_classes/workflows.py 92.30% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2606      +/-   ##
==========================================
- Coverage   93.05%   93.02%   -0.04%     
==========================================
  Files         486      486              
  Lines       49481    49528      +47     
==========================================
+ Hits        46047    46072      +25     
- Misses       3434     3456      +22     
Files with missing lines Coverage Δ
cognite/client/data_classes/__init__.py 100.00% <ø> (ø)
...sts/tests_unit/test_data_classes/test_workflows.py 100.00% <100.00%> (ø)
cognite/client/data_classes/workflows.py 95.98% <92.30%> (+0.07%) ⬆️

... and 12 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JustAnotherNormalDev JustAnotherNormalDev changed the title fix(workflows): support functionApp task type and unknown workflow task fallbacks [ CDF-27867] fix(workflows): support functionApp task type and unknown workflow task fallbacks May 6, 2026
@JustAnotherNormalDev JustAnotherNormalDev changed the title [ CDF-27867] fix(workflows): support functionApp task type and unknown workflow task fallbacks fix(workflows): support functionApp task type and unknown workflow task fallbacks May 6, 2026
Comment thread cognite/client/data_classes/workflows.py Outdated
…r functionApp

Co-authored-by: Cursor <cursoragent@cursor.com>
@JustAnotherNormalDev JustAnotherNormalDev changed the title fix(workflows): support functionApp task type and unknown workflow task fallbacks fix(workflows): route functionApp and unlisted tasks through unknown parameter/output types May 7, 2026
@JustAnotherNormalDev JustAnotherNormalDev changed the title fix(workflows): route functionApp and unlisted tasks through unknown parameter/output types fix(workflows): route unlisted tasks through unknown parameter/output types May 7, 2026
VerstraeteBert
VerstraeteBert previously approved these changes May 7, 2026
Copy link
Copy Markdown
Contributor

@VerstraeteBert VerstraeteBert left a comment

Choose a reason for hiding this comment

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

LGTM

Comment thread cognite/client/data_classes/workflows.py Outdated
Comment thread cognite/client/data_classes/workflows.py Outdated
return cls(task_type, output if isinstance(output, dict) else {})

@property
def task_type(self) -> str: # type: ignore[override]
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.

This should pretend to return a ValidTaskType

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Let me know if this works

Comment thread cognite/client/data_classes/workflows.py Outdated
Copy link
Copy Markdown
Contributor

@haakonvt haakonvt left a comment

Choose a reason for hiding this comment

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

A few comments, otherwise looks good!

Comment thread cognite/client/data_classes/workflows.py Outdated
VerstraeteBert
VerstraeteBert previously approved these changes May 8, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
VerstraeteBert
VerstraeteBert previously approved these changes May 8, 2026
UserWarning,
stacklevel=2,
)
params = self._parameters if isinstance(self._parameters, dict) else {}
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.

You ignore parameters if it is not a dict. That means your init should say dict rather than Any?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

agree. Its dict now. dict[str, Any]:

UserWarning,
stacklevel=2,
)
out = self._output if isinstance(self._output, dict) else {}
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.

Same question here

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.

I also dont think we should have any kind of such logic? The payload is unkown, so we should return what we got instantiated with

Copy link
Copy Markdown
Contributor Author

@JustAnotherNormalDev JustAnotherNormalDev May 8, 2026

Choose a reason for hiding this comment

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

i changed it to dict. But do you mean , remove the warn message as well?

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.

No the warning is great! I mean, if self._output is not dict we ignore it in the output. I don't think we should

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.

Reason: The unknown class should just accept what gets passed to it - maybe in the future you want this to be a list or whatever, then this would break

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

If you are exempting your data classes from automatic testing, you need to add a better explanation please

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

please ignore this one. i reverted it back. Pushed it by mistake . I had added it for testing.

JustAnotherNormalDev and others added 9 commits May 11, 2026 11:33
Merge origin/master. Align UnknownWorkflowTaskOutput typing with raw load.
Add TestUnknownWorkflowTaskParametersCogniteResourceParity for envelope round-trips.
Shorten test_base exclude comment for UnknownWorkflowTaskParameters.

Co-authored-by: Cursor <cursoragent@cursor.com>
…est; trim workflow tests

Co-authored-by: Cursor <cursoragent@cursor.com>
… wiring

Wrap non-dict payloads in an opaque dict so CogniteResource.load round-trips.
Build unknown parameters from task type plus parameters blob, not full task dict.
Narrow dynamic_task_type to str | None; document opaque wrap/unwrap in comments.
Keep UnknownWorkflowTaskParameters in generic CogniteResource base tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
UnknownWorkflowTaskParameters round-trips are covered by workflows opaque wrapper.

Co-authored-by: Cursor <cursoragent@cursor.com>
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