mikefarah/yq · error

cannot repeat string by a negative number (%v)

Error message

cannot repeat string by a negative number (%v)

What it means

When using '*' to repeat a string ('"ab" * 3'), yq parses the integer operand and rejects negative counts because strings.Repeat semantics for negative counts would yield an empty/meaningless result. The library treats a negative repeat count as a user error.

Source

Thrown at pkg/yqlib/operator_multiply.go:157

func repeatString(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
	var stringNode *CandidateNode
	var intNode *CandidateNode
	if lhs.Tag == "!!str" {
		stringNode = lhs
		intNode = rhs
	} else {
		stringNode = rhs
		intNode = lhs
	}
	target := lhs.CopyWithoutContent()
	target.UpdateAttributesFrom(stringNode, assignPreferences{})

	count, err := parseInt(intNode.Value)
	if err != nil {
		return nil, err
	} else if count < 0 {
		return nil, fmt.Errorf("cannot repeat string by a negative number (%v)", count)
	}
	maxResultLen := 10 * 1024 * 1024 // 10 MiB
	if count > 0 && len(stringNode.Value) > maxResultLen/count {
		return nil, fmt.Errorf("result of repeating string (%v bytes) by %v would exceed %v bytes", len(stringNode.Value), count, maxResultLen)
	}
	target.Value = strings.Repeat(stringNode.Value, count)

	return target, nil
}

func mergeObjects(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode, preferences multiplyPreferences) (*CandidateNode, error) {
	var results = list.New()

	// only need to recurse the array if we are doing a deep merge
	prefs := recursiveDescentPreferences{RecurseArray: preferences.DeepMergeArrays,
		TraversePreferences: traversePreferences{DontFollowAlias: true, IncludeMapKeys: true, ExactKeyMatch: true}}
	log.Debugf("merge - preferences.DeepMergeArrays %v", preferences.DeepMergeArrays)
	log.Debugf("merge - preferences.AppendArrays %v", preferences.AppendArrays)

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Clamp the count before repeating: '"ab" * ([0, (.n)] | max)' or guard with select(.n >= 0)
  2. Fix the source value producing the negative count
  3. If an empty result is desired, use count 0 instead of a negative number

Example fix

// before
yq '"-" * (.n - 10)' f.yml   // .n=8 -> cannot repeat string by a negative number (-2)
// after
yq '"-" * ([0, .n - 10] | max)' f.yml
Defensive patterns

Strategy: validation

Validate before calling

yq 'select(.n >= 0) | "ab" * .n' f.yml

Try / catch

// shell
out=$(yq '"ab" * .n' f.yml 2>&1) || { echo "bad count: $out"; exit 1; }

Prevention

When it happens

Trigger: An expression like '"abc" * -1' or '"x" * (0 - 5)', or a computed count that evaluates to a negative int, e.g. '"ab" * (1 - 3)'.

Common situations: Subtraction-based counters that go negative (e.g. repeat = desired - current when current > desired), config values read from files that are negative, sign errors in expressions.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05). Data as JSON: /api/errors/a8d5e9688e89cd8c. Report an issue: GitHub.