Skip to content

Enable Approval Workflows for All Assets with Flexible Assignee Sources#26055

Open
Copilot wants to merge 12 commits intomainfrom
copilot/enable-approval-workflows
Open

Enable Approval Workflows for All Assets with Flexible Assignee Sources#26055
Copilot wants to merge 12 commits intomainfrom
copilot/enable-approval-workflows

Conversation

Copy link
Contributor

Copilot AI commented Feb 24, 2026

Approval workflows were restricted to entities with a reviewers field. This lifts that restriction, introduces correct fallback semantics based on whether the entity schema supports reviewers at all, adds support for multiple assignee sources including specific users/teams, and generalizes approval task resolution and delete guards across all entity repositories.

Describe your changes:

I worked on several improvements to the approval workflow system:

1. Fix reviewers fallback logic (SetApprovalAssigneesImpl)

Previously, when assigneeSource = "reviewers" and the entity had no reviewers, the workflow fell back to owners. The correct behaviour is:

  • If the entity has a reviewers field but it is empty → auto-approve (no fallback to owners)
  • If the entity has no reviewers field (e.g. table) → fall back to owners; auto-approve if owners are also empty
source = "reviewers":
  ├─ entity HAS reviewers field (isSupportsReviewers=true)
  │   ├─ reviewers non-empty  →  assign to reviewers
  │   └─ reviewers empty      →  auto-approve  (no fallback to owners)
  └─ entity has NO reviewers field (e.g. table)
      ├─ owners non-empty     →  assign to owners
      └─ owners empty         →  auto-approve

source = "owners":
  └─ use owners directly; auto-approve if empty

2. Support multiple assignee sources

The assignees config now accepts assigneeSources — an array where each entry can be:

  • "reviewers" — entity's reviewers (with the corrected fallback semantics above)
  • "owners" — entity's owners
  • A specific entity link string, e.g. <#E::user::john.doe> — a named user or team

Multiple sources are unioned and deduplicated, enabling combinations such as:

{ "assigneeSources": ["reviewers", "<#E::user::alice>"] }
{ "assigneeSources": ["owners", "<#E::team::data-team>"] }
{ "assigneeSources": ["reviewers", "owners"] }
{ "assigneeSources": ["<#E::user::alice>", "<#E::user::bob>"] }

Invalid entity link strings are skipped with a warning rather than failing the whole task.

All legacy formats (assigneeSource single string, addReviewers: true) continue to work via fallback precedence: assigneeSourcesassigneeSourceaddReviewers.

3. Generalized ApprovalTaskWorkflow in EntityRepository

Previously each entity repository (GlossaryTermRepository, DataContractRepository, MetricRepository, DataProductRepository, TestCaseRepository, TagRepository) had its own duplicate ApprovalTaskWorkflow inner class. These are now removed and replaced by a single generic implementation in EntityRepository. The generic implementation:

  • Calls checkUpdatedByTaskAssignee (checks task assignees, not entity reviewers)
  • Delegates resolution to WorkflowHandler.resolveTask
  • Falls back to a direct entityStatus patch if the Flowable workflow record is missing

4. preDelete — task-assignee guard instead of reviewer guard

All per-entity preDelete overrides that previously blocked deletion by checking checkUpdatedByReviewer now call checkDeleteAllowedByTaskAssignee instead. This method:

  • Looks up the open RequestApproval task for the entity
  • Verifies the deleter is an assignee of that task
  • Allows deletion if no open task exists (workflow may not have started yet)

5. performTask — task-assignee check instead of reviewer check

checkUpdatedByReviewer is no longer called in any performTask implementation. The new checkUpdatedByTaskAssignee utility verifies that the acting user appears in the task's assignees list (including team membership expansion). RecognizerFeedbackTaskWorkflow in TagRepository is also updated.

6. v1.12.2 Java migration for addReviewers field

Created a Java-only migration (v1122) for MySQL and PostgreSQL that converts existing workflow definitions using the deprecated "assignees": {"addReviewers": true} format to the new "assignees": {"assigneeSources": ["reviewers"]} format. The migration uses WorkflowDefinitionRepository.createOrUpdate() (matching the v1105 pattern) so that Flowable also receives the updated workflow definition as part of the migration chain. The migration is idempotent and skips workflows that are already migrated or do not use addReviewers.

7. Updated seeded workflow JSON files

The bundled workflow definitions now use the new assigneeSources format directly:

  • GlossaryApprovalWorkflow.json — both ApproveGlossaryTerm and ApprovalForUpdates nodes updated
  • RecognizerFeedbackReviewWorkflow.jsonReviewFeedback node updated

All occurrences of "assignees": {"addReviewers": true} replaced with "assignees": {"assigneeSources": ["reviewers"]}.

Schema & Types

  • Added assigneeSources array field to userApprovalTask.json assignees config
  • assigneeSource (single enum) and addReviewers (boolean) retained as deprecated for backward compatibility
  • Updated generated TypeScript interface accordingly
  • Bootstrap SQL directories created at bootstrap/sql/migrations/native/1.12.2/

Type of change:

  • Bug fix
  • Improvement
  • New feature
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.


Summary by Gitar

  • Approval workflows now universally enabled:
    • All entity types supported (not just those with reviewers field); owners used as fallback for non-reviewer entities
    • Corrected fallback semantics: empty reviewers auto-approve (no fallback to owners)
  • Flexible assignee sources with backward compatibility:
    • New assigneeSources array supports reviewers, owners, and specific user/team entity links
    • Legacy formats (assigneeSource string, addReviewers boolean) via three-tier fallback precedence
    • Invalid entity links skip gracefully with warnings
  • Generalized workflow implementation:
    • Removed 6 duplicate ApprovalTaskWorkflow classes; single implementation in EntityRepository
    • Changed authorization from entity reviewers to actual task assignees; enables enforcement across all entity types
  • Data migration (v1.12.2):
    • Java-only migration converts addReviewers: trueassigneeSources: ["reviewers"] format
    • Idempotent; uses WorkflowDefinitionRepository.createOrUpdate() to sync with Flowable
  • Deletion authorization now task-driven:
    • IN_REVIEW entities deletable only by open task assignees (not entity reviewers)
    • Allows deletion if no task exists (workflow not started)

This will update automatically on new commits.

… support

Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Copilot AI changed the title [WIP] Enable approval workflows for all assets Enable Approval Workflows for all assets Feb 24, 2026
…-reviewer entities fall back to owners

Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Copilot AI changed the title Enable Approval Workflows for all assets Enable Approval Workflows for All Assets Feb 24, 2026

// Determine if we should add assignees from the entity's reviewers or owners.
// assigneeSource takes precedence; addReviewers is kept for backward compatibility.
boolean useReviewers =
Copy link
Contributor

Choose a reason for hiding this comment

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

We only have reviewers and owners as the source, what if the task assignee should be altogether a different user to be selected from drop down? if the fullyQualifiedName (fqn) is sent, we need to pick that up, there can be multiple inputs as well.
For example:

  1. we can send two user fqns
  2. We can choose reviewers and owners
  3. We can send reviewers and users
  4. owners and users

Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot address this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 1cf482c. The assignees config now accepts assigneeSources — an array where each entry can be:

  • "reviewers" — entity's reviewers (auto-approves if entity has reviewers field but it's empty)
  • "owners" — entity's owners
  • A specific entity link string, e.g. <#E::user::john.doe> — a named user or team

Multiple sources are unioned and deduplicated, so you can combine them freely:

{ "assigneeSources": ["reviewers", "<#E::user::alice>", "<#E::user::bob>"] }
{ "assigneeSources": ["owners", "<#E::team::data-team>"] }
{ "assigneeSources": ["reviewers", "owners"] }
{ "assigneeSources": ["<#E::user::alice>", "<#E::user::bob>"] }

All legacy formats (assigneeSource single string, addReviewers: true) still work via fallback precedence.

Copy link
Contributor

@yan-3005 yan-3005 left a comment

Choose a reason for hiding this comment

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

Also few Important points to note:

  1. We are only changing the assignees of the task in the workflows, we need to gracefully resolve the Feed resolution as well, Today, we have Feedresolution in the FeedRepository per entity, and only the entity with reviewers have the resolution in their corresponding repository.
    For example, check static class ApprovalTaskWorkflow in GlossaryTermRepository, DataContractRepository etc etc
    We need to generalise this into the EntityRepository only, now that we are going to allow the task resolution of all the entities in OpenMetadata.
    We have the resolve this Generically, not depending on the entity types.

  2. we have this function preDelete in all the repositories right? before deleting we check if the update is done by a reviewer or not, now that we are having approval tasks for people other than reviewers, we should not do this anymore, rather check if there is a task, and check if the assignees and the person who is deleting this entity match, if they match, we can allow the deletion, if not, we shouldnt allow it as there is a pending task and the task assignee should be the one to take deletion in their hands.

  3. in performTask in the separate repository tasks, in the static class ApprovalTaskWorkflow we have this function performTask, and there is this statement checkUpdatedByReviewer, this is no longer the case, we should substitute with the above comment, we should check if the task assignee is truly the person who is approving the task, if not dont allow this operation

  4. we also have this field
    "assignees": {
    "addReviewers": true
    },
    For example, check GlossaryApprovalWorkflow.json, this is a seeded one, there can be user created ones as well
    in the workflow config right? what are we doing with this now, now that we have the assignee source?
    if you are removing this, then write the migrations as well properly in 1.12.2 as a java migration only

…er entity links

Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 24, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • repository.apache.org
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher spotless:apply -pl openmetadata-service -q 20&#39; --output-dir /tmp/playwrightuser.email (dns block)
  • s3.amazonaws.com
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher spotless:apply -pl openmetadata-service -q 20&#39; --output-dir /tmp/playwrightuser.email (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Enable Approval Workflows for All Assets Enable Approval Workflows for All Assets with Flexible Assignee Sources Feb 24, 2026
@karanh37
Copy link
Contributor

Also few Important points to note:

  1. We are only changing the assignees of the task in the workflows, we need to gracefully resolve the Feed resolution as well, Today, we have Feedresolution in the FeedRepository per entity, and only the entity with reviewers have the resolution in their corresponding repository.
    For example, check static class ApprovalTaskWorkflow in GlossaryTermRepository, DataContractRepository etc etc
    We need to generalise this into the EntityRepository only, now that we are going to allow the task resolution of all the entities in OpenMetadata.
    We have the resolve this Generically, not depending on the entity types.
  2. we have this function preDelete in all the repositories right? before deleting we check if the update is done by a reviewer or not, now that we are having approval tasks for people other than reviewers, we should not do this anymore, rather check if there is a task, and check if the assignees and the person who is deleting this entity match, if they match, we can allow the deletion, if not, we shouldnt allow it as there is a pending task and the task assignee should be the one to take deletion in their hands.
  3. in performTask in the separate repository tasks, in the static class ApprovalTaskWorkflow we have this function performTask, and there is this statement checkUpdatedByReviewer, this is no longer the case, we should substitute with the above comment, we should check if the task assignee is truly the person who is approving the task, if not dont allow this operation
  4. we also have this field
    "assignees": {
    "addReviewers": true
    },
    For example, check GlossaryApprovalWorkflow.json, this is a seeded one, there can be user created ones as well
    in the workflow config right? what are we doing with this now, now that we have the assignee source?
    if you are removing this, then write the migrations as well properly in 1.12.2 as a java migration only

@copilot address

…2 migration

Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 24, 2026

Also few Important points to note:

  1. We are only changing the assignees of the task in the workflows, we need to gracefully resolve the Feed resolution as well, Today, we have Feedresolution...

Addressed in commit fd8ad13:

  1. Feed resolution generalized — Moved ApprovalTaskWorkflow into EntityRepository as a generic implementation. All per-entity repos (GlossaryTermRepository, DataContractRepository, MetricRepository, DataProductRepository, TestCaseRepository, TagRepository) now delegate to super.getTaskWorkflow() for approval tasks instead of duplicating the logic.

  2. preDelete — Each repo's preDelete now calls checkDeleteAllowedByTaskAssignee, which looks up the open RequestApproval task for the entity and checks whether the deleter is an assignee of that task. If no open task exists, deletion is allowed.

  3. performTask — The generic ApprovalTaskWorkflow.performTask calls checkUpdatedByTaskAssignee (checks task assignees, not entity reviewers). RecognizerFeedbackTaskWorkflow in TagRepository is also updated to use this.

  4. Migration — Created Java-only migration v1122 (mysql + postgres) that transforms "assignees": {"addReviewers": true}"assignees": {"assigneeSources": ["reviewers"]} in all workflow definitions. Bootstrap SQL directories at bootstrap/sql/migrations/native/1.12.2/ are also created. Legacy addReviewers and assigneeSource fields are preserved for backward compatibility as fallbacks.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • repository.apache.org
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher spotless:apply -pl openmetadata-service -q --noprofile (dns block)
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher compile -pl openmetadata-service -am -q -DskipTests p/bin/sh (dns block)
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher compile -pl openmetadata-service -am -q -DskipTests ash (dns block)
  • s3.amazonaws.com
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher spotless:apply -pl openmetadata-service -q --noprofile (dns block)
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher compile -pl openmetadata-service -am -q -DskipTests p/bin/sh (dns block)
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher compile -pl openmetadata-service -am -q -DskipTests ash (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

WorkflowDefinition workflow =
JsonUtils.readValue(
MAPPER.writeValueAsString(updatedNode), WorkflowDefinition.class);
collectionDAO.workflowDefinitionDAO().update(workflow);
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot This is not correct, Use WorkflowTransactionManager's createOrUpdateWorkflowDefinition function to update the workflow, check 1.10.5 migrationutil on how this is done as an example
By using the above method, we will deploy the new workflow to flowable in the method chain

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 525b6f3. The migration now uses WorkflowDefinitionRepository.createOrUpdate(null, updated, ADMIN_USER_NAME) (same pattern as v1105) so the updated workflow is deployed to Flowable as part of the migration chain.

…e for Flowable deployment

Co-authored-by: yan-3005 <81347100+yan-3005@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 24, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • repository.apache.org
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher spotless:apply -pl openmetadata-service -q (dns block)
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher compile -pl openmetadata-service -am -DskipTests (dns block)
  • s3.amazonaws.com
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher spotless:apply -pl openmetadata-service -q (dns block)
    • Triggering command: /usr/lib/jvm/temurin-21-jdk-amd64/bin/java /usr/lib/jvm/temurin-21-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.12/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenMetadata/OpenMetadata org.codehaus.plexus.classworlds.launcher.Launcher compile -pl openmetadata-service -am -DskipTests (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@yan-3005
Copy link
Contributor

@copilot Fix the seeded workflow jsons as well, Fix GlossaryApprovalWorkflow.json and RecognizerFeedbackReviewWorkflow.json with the default source as reviewers, fix it properly now

@github-actions
Copy link
Contributor

TypeScript types have been updated based on the JSON schema changes in the PR

@github-actions
Copy link
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 65%
65.74% (56546/86013) 45.22% (29630/65521) 47.96% (8923/18607)

@yan-3005 yan-3005 self-assigned this Feb 25, 2026
@gitar-bot
Copy link

gitar-bot bot commented Feb 25, 2026

🔍 CI failure analysis for 2075eaa: playwright-ci-postgresql (3, 6) had 6 test failures, primarily due to 500 Server Errors when deleting glossaries - NullPointerException caused by EntityReference.getName() returning null, likely related to the PR's entity repository changes.

Issue

The playwright-ci-postgresql (3, 6) job failed with 6 test failures:

Test Results:

  • ❌ 6 failed
  • ✅ 583 passed

Critical Error Pattern:
Multiple glossary deletion operations failed with 500 Server Error:

Failed to delete glossary: 500 Server Error
{
  "code": 500,
  "errorType": "UNHANDLED_SERVER_EXCEPTION",
  "message": "An exception with message [Cannot invoke "String.equals(Object)" because the return value of "org.***.schema.type.EntityReference.getName()" is null] was thrown while processing request."
}

At least 8 glossaries failed to delete with this same error.

Root Cause

This is a NullPointerException in the backend when processing entity references:

  1. EntityReference.getName() returns null during glossary deletion
  2. The code tries to call String.equals() on the null name, causing the NPE
  3. This results in 500 Server Error responses

Likely Related to PR Changes:

This PR modifies entity repositories and introduces new task handling logic:

  • Generalized ApprovalTaskWorkflow in EntityRepository
  • Added checkDeleteAllowedByTaskAssignee logic in preDelete methods
  • Modified entity reference handling for task assignees

The PR's commit c72f7406a9 titled "Test cases, NPE in threads and tasks for entityLink" explicitly mentions NPE fixes, suggesting this issue was anticipated but may not be fully resolved.

Other Test Failures:

  • Error: locator.fill: value: expected string, got undefined (data issue)
  • Error: expect(locator).toBeVisible() failed (timing/flakiness)
  • TypeError: Cannot read properties of undefined (reading '0') (data issue)
  • Error: page.waitForResponse: Target page, context or browser has been closed (browser crash)
  • Error: strict mode violation: getByTestId('glossary-container') resolved to 8 elements (selector issue)

Details

  • Commit analyzed: 2075eaab7a43e5fba25bceff0e3def8da72a3f7c
  • Job affected: playwright-ci-postgresql (3, 6) [64850145023]
  • Failure rate: 1.02% (6 failures out of 589 total tests)
  • Primary issue: NullPointerException in EntityReference.getName() during glossary deletion
  • Related files: Entity repository code, particularly deletion handling

Relationship to Other Failures

For commit 2075eaab7a43e5fba25bceff0e3def8da72a3f7c, we now have:

  1. Code issue (integration tests): Schema/code generation mismatch for addOwners field
  2. Infrastructure issue (maven-collate-ci): External workflow timeout
  3. Backend NPE issue (this job): EntityReference.getName() returning null during glossary deletion - directly related to PR changes
  4. E2E test flakiness (playwright shard 6): Standard flaky tests

Fix Required

Investigate why EntityReference.getName() returns null during entity deletion, particularly in the context of:

  1. The new checkDeleteAllowedByTaskAssignee logic
  2. Task assignee entity reference handling
  3. Entity reference creation/population in the generalized ApprovalTaskWorkflow

The code should either ensure EntityReference names are never null, or add null checks before calling methods on the name.

Tip

Comment Gitar fix CI or enable auto-apply: gitar auto-apply:on

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud
Copy link

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend safe to test Add this label to run secure Github workflows on PRs To release Will cherry-pick this PR into the release branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants