larksuite/cli · error

must be finite

Error message

must be finite

What it means

parseFiniteFloatBits (used by parseFiniteFloat and shapeForType) rejects NaN and +/-Inf because JSON cannot represent them and default/bound values must marshal cleanly. When strconv.ParseFloat succeeds but returns a non-finite value, this error replaces it with a clear 'must be finite' message. It is a compile-time/tag-value validation error.

Source

Thrown at shortcuts/common/typed_compile_args.go:554

			result.Encoding = typedCLIEncoding(value)
		default:
			return result, fmt.Errorf("unknown cli token %q", key)
		}
	}
	return result, nil
}

func parseFiniteFloat(value string) (float64, error) {
	return parseFiniteFloatBits(value, 64)
}

func parseFiniteFloatBits(value string, bits int) (float64, error) {
	parsed, err := strconv.ParseFloat(value, bits)
	if err != nil {
		return 0, err
	}
	if math.IsNaN(parsed) || math.IsInf(parsed, 0) {
		return 0, fmt.Errorf("must be finite")
	}
	return parsed, nil
}

func parseNonnegativeInt(value string) (int, error) {
	parsed, err := strconv.ParseUint(value, 10, 31)
	if err != nil {
		return 0, fmt.Errorf("must be a nonnegative integer: %w", err)
	}
	return int(parsed), nil
}

func indirectType(t reflect.Type) reflect.Type {
	for t.Kind() == reflect.Pointer {
		t = t.Elem()
	}
	return t
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Replace the NaN/Inf value with a finite number
  2. If a max value means 'unbounded', omit maximum/minItems-style bounds instead of using Inf
  3. Clamp or sanitize the value before assigning it as a default

Example fix

// before
Max: func() float64 { return math.Inf(1) }()
// after
// omit the maximum bound entirely, or use a concrete finite limit
Max: 1e12
Defensive patterns

Strategy: validation

Validate before calling

func isFinite(f float64) bool { return !math.IsNaN(f) && !math.IsInf(f, 0) }
if !isFinite(defaultVal) { return fmt.Errorf("default must be finite") }

Type guard

func isFiniteFloat(v any) bool {
	f, ok := v.(float64)
	return ok && !math.IsNaN(f) && !math.IsInf(f, 0)
}

Prevention

When it happens

Trigger: Passing a default, minimum, or maximum value of NaN, +Inf, or -Inf (e.g. from a tag like `default:"NaN"` or computed input) to a float-typed schema value.

Common situations: Using sentinel constants like math.Inf(1) or math.NaN() as defaults; parsing user config that contains 'Infinity' or 'NaN' strings.

Related errors


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