mikefarah/yq · error

cannot encode %v as URI, can only operate on strings. Please

Error message

cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string

What it means

The URI encoder (@uri / ur operation) only accepts string nodes. If the node's tag is not !!str, it refuses to encode, telling you to convert the value to a string first (e.g. with string interpolation or the string operator). This prevents silently encoding numbers/booleans/objects in surprising ways.

Source

Thrown at pkg/yqlib/encoder_uri.go:32

func NewUriEncoder() Encoder {
	return &uriEncoder{}
}

func (e *uriEncoder) CanHandleAliases() bool {
	return false
}

func (e *uriEncoder) PrintDocumentSeparator(_ io.Writer) error {
	return nil
}

func (e *uriEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
	return nil
}

func (e *uriEncoder) Encode(writer io.Writer, node *CandidateNode) error {
	if node.guessTagFromCustomType() != "!!str" {
		return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
	}
	_, err := writer.Write([]byte(url.QueryEscape(node.Value)))
	return err
}

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Force string conversion before encoding: `yq '.val | tostring | @uri'` or pipe through string interpolation `\"\(.val)\"`.
  2. Quote the value in the source YAML so it parses as a string (`version: \"1.20\"`).
  3. Select a string field instead of the whole map: `yq '.name | @uri'`.
  4. For numbers, format explicitly: `yq '.port | format_int(10) | @uri'`.

Example fix

// before
yq '.port | @uri' config.yaml      # error: !!int
// after
yq '.port | tostring | @uri' config.yaml
Defensive patterns

Strategy: type-guard

Validate before calling

yq '.val | tag' in.yaml  # must print "!!str" before @uri

Type guard

// shell pre-check
[ "$(yq '.val | tag' in.yaml)" = "!!str" ] || echo "needs tostring"

Try / catch

// Go
if err := uriEnc.Encode(w, node); err != nil {
    if strings.Contains(err.Error(), "can only operate on strings") {
        // convert node to !!str (tostring / interpolation) and retry
    }
}

Prevention

When it happens

Trigger: Running `yq '@uri' 123` or `yq '.val | @uri'` where .val is a number, boolean, null, or a map/sequence — any node whose guessed tag is not !!str.

Common situations: Querying numeric config values (ports, ids) and trying to URI-encode them; forgetting that YAML parses bare tokens as numbers/booleans (e.g. `version: 1.20` becomes a float); encoding entire objects instead of scalar string fields.

Related errors


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