larksuite/cli · error

Input.Relations[%d].Kind %q is invalid

Error message

Input.Relations[%d].Kind %q is invalid

What it means

compileRelations validates each entry of Input.Relations against the known relation kinds: exactly_one, at_least_one, co_occur, conflicts (>=2 params) and requires (exactly 2 params). An unrecognized Kind string produces this compile-time error, preventing malformed relation declarations from reaching the runtime.

Source

Thrown at shortcuts/common/typed_compile_contract.go:24

import (
	"encoding/json"
	"fmt"
	"strings"
)

func compileRelations(definitions []typedRelation, fieldByName map[string]int) ([]compiledRelation, error) {
	result := make([]compiledRelation, 0, len(definitions))
	seen := make(map[string]struct{})
	for i, definition := range definitions {
		minimum := 2
		exact := 0
		switch definition.Kind {
		case typedRelationExactlyOne, typedRelationAtLeastOne, typedRelationCoOccur, typedRelationConflicts:
		case typedRelationRequires:
			exact = 2
		default:
			return nil, fmt.Errorf("Input.Relations[%d].Kind %q is invalid", i, definition.Kind)
		}
		if exact > 0 && len(definition.Params) != exact || exact == 0 && len(definition.Params) < minimum {
			return nil, fmt.Errorf("Input.Relations[%d] kind %s has invalid param count %d", i, definition.Kind, len(definition.Params))
		}
		if definition.Presence != typedPresenceExplicit && definition.Presence != typedPresenceNonZero {
			return nil, fmt.Errorf("Input.Relations[%d].Presence %q is invalid", i, definition.Presence)
		}
		if definition.Stage != typedStageSourcePreRun && definition.Stage != typedStageAfterPrepare {
			return nil, fmt.Errorf("Input.Relations[%d].Stage %q is invalid", i, definition.Stage)
		}
		compiled := compiledRelation{kind: definition.Kind, presence: definition.Presence, stage: definition.Stage}
		local := make(map[string]struct{})
		for _, name := range definition.Params {
			field, ok := fieldByName[name]
			if !ok {
				return nil, fmt.Errorf("Input.Relations[%d] references unknown param --%s", i, name)
			}
			if _, duplicate := local[name]; duplicate {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Use the exported typed constants (typedRelationExactlyOne, typedRelationAtLeastOne, typedRelationCoOccur, typedRelationConflicts, typedRelationRequires) rather than raw strings
  2. Fix the spelling of the Kind value to match one of the supported constants
  3. Run the shortcut package's compile tests to catch this before startup

Example fix

// before
Relations: []typedRelation{{Kind: "exactlyone", Params: []string{"a","b"}}}
// after
Relations: []typedRelation{{Kind: typedRelationExactlyOne, Params: []string{"a","b"}}}
Defensive patterns

Strategy: validation

Validate before calling

func knownRelationKind(k typedRelationKind) bool {
	switch k {
	case typedRelationExactlyOne, typedRelationAtLeastOne,
		typedRelationCoOccur, typedRelationConflicts, typedRelationRequires:
		return true
	}
	return false
}

Type guard

func isTypedRelationKind(v any) bool {
	k, ok := v.(typedRelationKind)
	return ok && knownRelationKind(k)
}

Prevention

When it happens

Trigger: Declaring a relation with a typo'd or invented Kind, e.g. Kind: "exactlyone" or "mutually-exclusive", in a typed input definition.

Common situations: Hand-writing relation kinds instead of using the typed constants (typedRelationExactlyOne, etc.); rebasing code across renamed kind values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/f521ec8836b6ab04. Report an issue: GitHub.