Skip to content

fix(base): validate workflow message action shapes - #2092

Open
huarenmin13 wants to merge 1 commit into
larksuite:mainfrom
huarenmin13:agent/generalize-workflow-contracts
Open

fix(base): validate workflow message action shapes#2092
huarenmin13 wants to merge 1 commit into
larksuite:mainfrom
huarenmin13:agent/generalize-workflow-contracts

Conversation

@huarenmin13

@huarenmin13 huarenmin13 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Add shared preflight validation for the known LarkMessageAction request shape used by workflow create and update. This is a focused replacement for #2078: it keeps reusable schema validation while excluding case-specific unsupported-trigger guidance and duplicated field advice in command help.

Changes

  • Validate LarkMessageAction.data as an object with non-empty receiver and content arrays for both create and update.
  • Keep send_to_everyone and btn_list optional, but validate their boolean/array types when supplied.
  • Return field-specific typed validation errors that identify --json and the failing indexed path.
  • Make the workflow schema the single source of truth for these field contracts.
  • Add table-driven unit coverage, real-binary dry-run coverage, and an embedded-skill delivery check.

Test Plan

  • make unit-test
  • go vet ./...
  • gofmt -l .
  • go mod tidy (no changes)
  • go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 run --new-from-rev=upstream/main
  • make build
  • Targeted create/update dry-run E2E with the branch-built binary
  • skills read E2E confirms the updated embedded workflow schema is delivered

Live workflow E2E was not run; this change is fully covered at the local preflight and dry-run boundaries and does not call the service.

Related Issues

改动范围: Base workflow create/update 预检、LarkMessageAction schema、单测、dry-run E2E 与嵌入 skill 交付测试
思考过程: 新 PR 基于最新 upstream/main,仅保留可复用的消息动作契约;排除原 PR 的单 case unsupported-trigger 文案和 help 重复事实
改动原因: 修复无效消息动作直到服务端才报错的问题,并用通用结构约束替换面向单个评测样例的过拟合改动
Break Change: 行为 breaking | 无效 LarkMessageAction 在本地预检阶段失败

Co-authored-by: BASE Infra Harness ai@base-infra-harness.noreply.local
AI-SHA256: 5367e32fc010a944e95b4109e107077d0b05e0216c2de20004a29c5a22b56bd3

Summary by CodeRabbit

  • New Features

    • Added validation for workflow message actions in workflow create and update commands.
    • Validates required receiver and content arrays, plus optional field types.
    • Supports omitting optional send_to_everyone and btn_list fields.
  • Bug Fixes

    • Invalid, well-formed workflow JSON is now rejected with actionable validation errors.
  • Documentation

    • Updated workflow schema documentation to reflect optional fields.

1. Share LarkMessageAction preflight validation across workflow create and update
2. Validate required arrays and optional field types with field-specific typed errors
3. Keep field contracts in the workflow schema and cover unit, dry-run,
    and embedded skill delivery paths

说明:
- Deliberately excludes case-specific unsupported-trigger guidance from PR larksuite#2078

```ai-signature
改动范围: Base workflow create/update 预检、LarkMessageAction schema、单测、dry-run E2E 与嵌入 skill 交付测试
思考过程: create 和 update 复用同一校验器,只校验已知消息动作的稳定结构;其他 workflow step 继续由服务端负责,避免不完整的客户端业务解释器
改动原因: 在请求前拦截 receiver/content 缺失和可选字段类型错误,同时移除单 case SOP 与 help 重复事实导致的过拟合方向
Break Change: 行为 breaking | 过去会发送的无效 LarkMessageAction 现在返回 typed validation error
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 9d629364e3a6b4db5c842bee23269dd7fdb275d78afbee8747efdaf18abf9979
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Workflow create and update now perform semantic validation for LarkMessageAction steps. Required fields and optional field types are checked, while unit tests, CLI dry-run tests, schema contract tests, and coverage documentation are updated.

Changes

Workflow message validation

Layer / File(s) Summary
Message action validation entry points
shortcuts/base/workflow_*.go
Create and update pass parsed JSON bodies to shared validation that checks required receiver and content arrays plus optional field types.
Shared validation test coverage
shortcuts/base/workflow_message_validation_test.go
Tests cover invalid and accepted message action shapes for both workflow commands.
Dry-run and schema contract coverage
tests/cli_e2e/base/*, skills/lark-base/references/lark-base-workflow-schema.md
CLI tests verify serialization and validation, while the schema marks send_to_everyone and btn_list as optional. Coverage documentation records both commands as covered.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • larksuite/cli#2078: Modifies the same workflow validation paths and related LarkMessageAction tests.

Suggested reviewers: liangshuo-1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: validating workflow message action shapes.
Description check ✅ Passed The description follows the template and includes summary, changes, test plan, and related issues.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added domain/base PR touches the base domain size/M Single-domain feat or fix with limited business impact labels Jul 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
shortcuts/base/workflow_message_validation.go (1)

41-79: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract helpers to remove duplicated required/optional field checks.

The receiver/content blocks (Lines 41-57) and the send_to_everyone/btn_list blocks (Lines 59-79) each repeat the same "assert type, build path, return typed error" pattern with only the field name/type/hint differing.

♻️ Proposed refactor
+func requireNonEmptyArray(data map[string]interface{}, dataPath, field string) error {
+	path := dataPath + "." + field
+	arr, ok := data[field].([]interface{})
+	if !ok || len(arr) == 0 {
+		return workflowMessageActionShapeError(
+			path,
+			"a non-empty JSON array",
+			fmt.Sprintf("Set %s to a non-empty JSON array.", path),
+		)
+	}
+	return nil
+}
+
 		receiverPath := dataPath + ".receiver"
-		if receiver, ok := data["receiver"].([]interface{}); !ok || len(receiver) == 0 {
-			return workflowMessageActionShapeError(
-				receiverPath,
-				"a non-empty JSON array",
-				fmt.Sprintf("Set %s to a non-empty JSON array.", receiverPath),
-			)
+		if err := requireNonEmptyArray(data, dataPath, "receiver"); err != nil {
+			return err
 		}
 
-		contentPath := dataPath + ".content"
-		if content, ok := data["content"].([]interface{}); !ok || len(content) == 0 {
-			return workflowMessageActionShapeError(
-				contentPath,
-				"a non-empty JSON array",
-				fmt.Sprintf("Set %s to a non-empty JSON array.", contentPath),
-			)
+		if err := requireNonEmptyArray(data, dataPath, "content"); err != nil {
+			return err
 		}

A similar helper (accepting a func(interface{}) bool type-check and hint text) could unify the send_to_everyone/btn_list optional-field blocks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/workflow_message_validation.go` around lines 41 - 79, Extract
reusable validation helpers for the required receiver/content checks and
optional send_to_everyone/btn_list checks in the workflow message validation
flow. Parameterize each helper with the field name, type predicate or expected
type, and hint text, while preserving non-empty-array requirements for
receiver/content and allowing an empty btn_list. Update the surrounding
validation logic to use these helpers and retain the existing typed errors and
paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@shortcuts/base/workflow_message_validation.go`:
- Around line 41-79: Extract reusable validation helpers for the required
receiver/content checks and optional send_to_everyone/btn_list checks in the
workflow message validation flow. Parameterize each helper with the field name,
type predicate or expected type, and hint text, while preserving non-empty-array
requirements for receiver/content and allowing an empty btn_list. Update the
surrounding validation logic to use these helpers and retain the existing typed
errors and paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e1543b50-fa00-429f-88f0-b7e561663b97

📥 Commits

Reviewing files that changed from the base of the PR and between 358cd06 and 3b49167.

📒 Files selected for processing (8)
  • shortcuts/base/workflow_create.go
  • shortcuts/base/workflow_message_validation.go
  • shortcuts/base/workflow_message_validation_test.go
  • shortcuts/base/workflow_update.go
  • skills/lark-base/references/lark-base-workflow-schema.md
  • tests/cli_e2e/base/coverage.md
  • tests/cli_e2e/base/workflow_dryrun_test.go
  • tests/cli_e2e/base/workflow_skill_contract_test.go

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

Labels

domain/base PR touches the base domain size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant