Skip to content

--exclude-tags crashes with e.some is not a function when request tags are defined as a string #7431

@jdelpierre

Description

@jdelpierre

Environment

  • @usebruno/cli version: 3.1.3
  • @usebruno/common version: 0.18.0
  • Node.js version: v24.11.1
  • OS: macOS 25.3.0

Description

When using --exclude-tags with bru run, the CLI crashes with e.some is not a function if any .bru file in the collection has a tags field defined with a single value (e.g. tags: ignore).

Root Cause

1. The parser returns a string, not an array

When a .bru file has:

meta {
  name: My request
  type: http
  seq: 1
  tags: ignore
}

The parsed value of item.tags is the string "ignore", not an array ["ignore"].

2. isRequestTagsIncluded in @usebruno/common assumes an array

// @usebruno/common/dist/cjs/index.js
(e, a, r) => {
  const n = 0 === a.length || e.some((e => a.includes(e)));  // ← crashes if e is a string
  const i = r.length > 0 && e.some((e => r.includes(e)));   // ← crashes if e is a string
  return n && !i;
}

String.prototype.some does not exist → TypeError: e.some is not a function.

3. The call site in run.js does not normalize the value

// src/commands/run.js:929
requestItems = requestItems.filter((item) => {
  return isRequestTagsIncluded(item.tags, includeTags, excludeTags); // item.tags can be a string
});

Note: prepare-request.js:46 already does tags: item.tags || [], but this normalization happens after the filter at line 929, so the raw unparsed value is used.

Steps to Reproduce

  1. Create a .bru file with a single tag:
meta {
  name: My request
  type: http
  seq: 1
  tags: ignore
}

get {
  url: https://example.com
  body: none
  auth: none
}
  1. Run:
bru run "./" --exclude-tags ignore
  1. Result:
Something went wrong
e.some is not a function

Expected Behavior

The CLI should handle tags as either a string or an array and exclude matching requests without crashing.

Proposed Fix

In src/commands/run.js, normalize item.tags to an array before passing it to isRequestTagsIncluded:

// Before
requestItems = requestItems.filter((item) => {
  return isRequestTagsIncluded(item.tags, includeTags, excludeTags);
});

// After
requestItems = requestItems.filter((item) => {
  const tags = Array.isArray(item.tags)
    ? item.tags
    : item.tags
      ? String(item.tags).split(',').map((t) => t.trim())
      : [];
  return isRequestTagsIncluded(tags, includeTags, excludeTags);
});

Or alternatively, fix it at the isRequestTagsIncluded level in @usebruno/common to accept both strings and arrays:

const toArray = (v) => !v ? [] : Array.isArray(v) ? v : String(v).split(',').map(t => t.trim());

(e, a, r) => {
  const tags = toArray(e);
  const n = a.length === 0 || tags.some(t => a.includes(t));
  const i = r.length > 0 && tags.some(t => r.includes(t));
  return n && !i;
}

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions