grafana/k6 · error · InvalidSelectorError

Unexpected end of selector while parsing selector `${selecto

Error message

Unexpected end of selector while parsing selector `${selector}`

What it means

Raised as a JavaScript TypeError when a script assigns a non-primitive value to a metadata key through the execution module's dynamic metadata object (execution.vu.meta). The Set method at internal/js/modules/k6/execution/execution.go:428 delegates to common.ApplyCustomUserMetadata (js/common/tags.go:60), which accepts only reflect.String, Bool, Int64 and Float64 kinds; anything else (objects, arrays, null, undefined, BigInt, functions) returns this error, which Set re-raises via runtime.NewTypeError. Note the value is also stringified on success (val.String()), the same restriction that applies to vu.tags.

Source

Thrown at internal/js/modules/k6/browser/common/js/injected_script.js:989

// packages/playwright-core/src/utils/isomorphic/cssParser.ts
var InvalidSelectorError = class extends Error {
};

// packages/playwright-core/src/utils/isomorphic/selectorParser.ts
function parseAttributeSelector(selector, allowUnquotedStrings) {
  let wp = 0;
  let EOL = selector.length === 0;
  const next = () => selector[wp] || "";
  const eat1 = () => {
    const result2 = next();
    ++wp;
    EOL = wp >= selector.length;
    return result2;
  };
  const syntaxError = (stage) => {
    if (EOL)
      throw new InvalidSelectorError(`Unexpected end of selector while parsing selector \`${selector}\``);
    throw new InvalidSelectorError(`Error while parsing selector \`${selector}\` - unexpected symbol "${next()}" at position ${wp}` + (stage ? " during " + stage : ""));
  };
  function skipSpaces() {
    while (!EOL && /\s/.test(next()))
      eat1();
  }
  function isCSSNameChar(char) {
    return char >= "\x80" || char >= "0" && char <= "9" || char >= "A" && char <= "Z" || char >= "a" && char <= "z" || char >= "0" && char <= "9" || char === "_" || char === "-";
  }
  function readIdentifier() {
    let result2 = "";
    skipSpaces();
    while (!EOL && isCSSNameChar(next()))
      result2 += eat1();
    return result2;
  }
  function readQuotedString(quote) {
    let result2 = eat1();

View on GitHub (pinned to 93accf6570)

Solutions

  1. Assign only string, number, or boolean values: `execution.vu.meta.userId = 42;` or `execution.vu.meta.plan = 'pro';`
  2. Serialize complex data first: `execution.vu.meta.payload = JSON.stringify(obj);`
  3. If the value may be null/undefined, default it: `execution.vu.meta.k = v ?? 'n/a';`
  4. Remove a key with `delete execution.vu.meta.mykey;` instead of assigning null
  5. Remember values are stored as their string representation; read them back as strings, not as the original type

Example fix

// before
execution.vu.meta.user = { id: 42, plan: 'pro' }; // TypeError: only String, Boolean and Number accepted

// after
execution.vu.meta.userId = 42;
execution.vu.meta.plan = 'pro';
// or, if structure must be kept:
execution.vu.meta.user = JSON.stringify({ id: 42, plan: 'pro' });
Defensive patterns

Strategy: type-guard

Validate before calling

const META_TYPES = new Set(['string', 'number', 'boolean']);

function safeSetMeta(key, value) {
  if (!META_TYPES.has(typeof value)) {
    throw new Error(
      `metadata '${key}' must be string, number or boolean, got ${typeof value}`
    );
  }
  execution.vu.meta[key] = value;
}

Type guard

const isMetaValue = (v) =>
  typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean';

Try / catch

try {
  execution.vu.meta[key] = value;
} catch (e) {
  if (e instanceof TypeError && /metric metadata/.test(e.message)) {
    execution.vu.meta[key] = JSON.stringify(value); // or skip/log
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Executing `execution.vu.meta['mykey'] = value` inside a script where value is an object, array, null, undefined, a function, or a BigInt. ExportType() returning nil (null/undefined) falls to reflect.Invalid and hits the default branch. Passing a variable read from an environment (string is fine) vs. parsed JSON (`JSON.parse(envVar)` yields objects/numbers) commonly trips it, as does reusing an options object as metadata.

Common situations: Scripts migrating from tags to metadata while assuming structured values are allowed; passing iteration data such as `{userId: 1}` instead of scalar values; setting metadata from untyped sources like environment variables parsed with JSON.parse; copying an options object (exec, env, tags) into vu.meta.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/24b1954559d08393. Report an issue: GitHub.