googleapis/mcp-toolbox · error

unable to parse element #%d: %w

Error message

unable to parse element #%d: %w

What it means

After validating the array itself, ArrayParameter.Parse calls Items.Parse on each element. If any element fails its own parse/validation (wrong type, not allowed, excluded, nested map failure, etc.), the error is wrapped as 'unable to parse element #%d' with the zero-based index.

Source

Thrown at internal/util/parameters/parameters.go:1166

	return false
}

func (p *ArrayParameter) Parse(v any) (any, error) {
	arrVal, ok := v.([]any)
	if !ok {
		return nil, &ParseTypeError{p.Name, p.Type, v}
	}
	if !p.IsAllowedValues(arrVal) {
		return nil, fmt.Errorf("%s is not an allowed value", arrVal)
	}
	if p.IsExcludedValues(arrVal) {
		return nil, fmt.Errorf("%s is an excluded value", arrVal)
	}
	rtn := make([]any, 0, len(arrVal))
	for idx, val := range arrVal {
		val, err := p.Items.Parse(val)
		if err != nil {
			return nil, fmt.Errorf("unable to parse element #%d: %w", idx, err)
		}
		rtn = append(rtn, val)
	}
	return rtn, nil
}

func (p *ArrayParameter) GetAuthServices() []ParamAuthService {
	return p.AuthServices
}

func (p *ArrayParameter) GetDefault() any {
	if p.Default == nil {
		return nil
	}
	return *p.Default
}

func (p *ArrayParameter) GetItems() Parameter {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Look at the element index in the wrapped message and check the inner error for the root cause.
  2. Ensure every element matches the declared items type (string/integer/boolean/float/array/map).
  3. Pre-validate the payload client-side against the tool's parameter manifest before invoking.

Example fix

// before
{"ids": [1, 2, "three"]}  // items type: integer
// after
{"ids": [1, 2, 3]}
Defensive patterns

Strategy: type-guard

Validate before calling

const itemsType = 'integer';
body.ids.forEach((el, i) => {
  if (typeof el !== 'number') throw new Error(`element #${i} is not an integer`);
});

Type guard

function isArrayOf(v, pred) { return Array.isArray(v) && v.every(pred); }
// usage: isArrayOf(body.ids, n => Number.isInteger(n))

Try / catch

try {
  await invokeTool('my_tool', body);
} catch (e) {
  if (/unable to parse element #(\d+)/.test(e.message)) {
    const idx = e.message.match(/#(\d+)/)[1];
    console.error(`Fix array element at index ${idx}: ${e.message}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Sending an array where at least one element does not satisfy the items schema — e.g. array of integers with one string element, or array items having their own allowedValues that an element violates.

Common situations: Mixed-type arrays from dynamic client code; strings like '1' instead of integers 1; nested arrays whose inner element fails validation.

Understand the failure class

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/0db05f551aab5e7c. Report an issue: GitHub.