From aa2ce13be46c771b1f1952e7a5e319c9e445fcbb Mon Sep 17 00:00:00 2001 From: Lukas Bindreiter Date: Wed, 12 Nov 2025 15:39:20 +0100 Subject: [PATCH] Disallow empty task groups --- apis/workflows/v1/core.proto | 7 ++++++- apis/workflows/v1/job.proto | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apis/workflows/v1/core.proto b/apis/workflows/v1/core.proto index 84dc688..cfacaf0 100644 --- a/apis/workflows/v1/core.proto +++ b/apis/workflows/v1/core.proto @@ -255,7 +255,12 @@ message TaskSubmissionGroup { // The input parameters for each task. // We explicitly don't group the fields into a submessage and then have a single repeated field for that submessage, // to enable packed encoding of the repeated fields. - repeated bytes inputs = 2 [(buf.validate.field).repeated.items.bytes.max_len = 2048]; + repeated bytes inputs = 2 [(buf.validate.field).repeated = { + min_items: 1 // we don't allow empty submission groups + items: { + bytes: {max_len: 2048} + } + }]; // Index of the task identifier in the identifier_lookup field of the containing TaskSubmissions message // for each task. repeated uint64 identifier_pointers = 3; diff --git a/apis/workflows/v1/job.proto b/apis/workflows/v1/job.proto index 4f09155..cb1ffc1 100644 --- a/apis/workflows/v1/job.proto +++ b/apis/workflows/v1/job.proto @@ -14,6 +14,12 @@ option features.field_presence = IMPLICIT; // SubmitJobRequest submits and schedules a job for execution. The job can have multiple root tasks. message SubmitJobRequest { + option (buf.validate.message).cel = { + id: "submit_job_request.tasks_required" + message: "At least one task must be submitted." + expression: "(this.tasks != null && this.tasks.task_groups.size() > 0) || this.legacy_tasks.size() > 0" + }; + // The root tasks for the job. TaskSubmissions tasks = 5; // The name of the job.