cheeriojs/cheerio · error · TypeError
Bad combination of arguments.
Error message
Bad combination of arguments.
What it means
Cheerio's attr() method only accepts certain argument combinations. When the second argument (value) is a function, the first argument (name) must be a string attribute name. Calling attr() with a function value but a non-string name (e.g. an object map combined with a function) is invalid and throws immediately.
Source
Thrown at src/api/attributes.ts:204
* @see {@link https://api.jquery.com/attr/}
*/
export function attr<T extends AnyNode>(
this: Cheerio<T>,
values: Record<string, string | null>,
): Cheerio<T>;
export function attr<T extends AnyNode>(
this: Cheerio<T>,
name?: string | Record<string, string | null>,
value?:
| string
| null
| ((this: Element, i: number, attrib: string) => string | null),
): string | Cheerio<T> | undefined | Record<string, string> {
// Set the value (with attr map support)
if (typeof name === 'object' || value !== undefined) {
if (typeof value === 'function') {
if (typeof name !== 'string') {
throw new TypeError('Bad combination of arguments.');
}
return domEach(this, (el, i) => {
if (isTag(el)) setAttr(el, name, value.call(el, i, el.attribs[name]));
});
}
return domEach(this, (el) => {
if (!isTag(el)) return;
if (typeof name === 'object') {
for (const [objName, objValue] of Object.entries(name)) {
setAttr(el, objName, objValue);
}
} else {
if (typeof name !== 'string') {
throw new TypeError('Bad combination of arguments.');
}
setAttr(el, name, value ?? null);
}View on GitHub (pinned to a1be131f9b)
Solutions
- Change the call to pass a string attribute name with the function: attr('href', (i, old) => ...)
- If setting multiple attributes, drop the function and pass only the object: attr({href: '...', id: '...'})
- Enable TypeScript types so the invalid overload is caught at compile time
Example fix
// before
$('img').attr({ src: 'a.png' }, (i, old) => old);
// after
$('img').attr('src', (i, old) => old); Defensive patterns
Strategy: type-guard
Validate before calling
const isAttrFnCall = (name: unknown, value: unknown) =>
typeof value === 'function' ? typeof name === 'string' : typeof name === 'string' || typeof name === 'object';
if (!isAttrFnCall(name, value)) throw new Error('Invalid attr() arguments'); Type guard
function isValidAttrArgs(
name: unknown,
value?: unknown,
): name is string | Record<string, string> {
if (typeof value === 'function') return typeof name === 'string';
return typeof name === 'string' || (typeof name === 'object' && name !== null);
} Try / catch
try { $('a').attr(name, value); } catch (e) { if (e instanceof TypeError && e.message === 'Bad combination of arguments.') { /* log and fix args */ } else throw e; } Prevention
- Use TypeScript overloads — they reject invalid attr() combos at compile time
- Never combine an object map with a function value
- Wrap dynamic selector/attr code in small typed helpers
When it happens
Trigger: Calling $('.x').attr({...}, function(){...}) — i.e. passing an object of attributes as the first argument AND a function as the second argument. The function-value overload requires attr(name: string, fn).
Common situations: Copy-pasting between jQuery-style code where option objects and callbacks were mixed; refactoring attr calls and accidentally leaving both an options object and a callback; TypeScript users bypassing types with any.
Related errors
- Unexpected type of selector
- Expected a string
- The content-type "${mimeType.essence}" is neither HTML nor X
- cheerio.load() expects a string
AI-assisted analysis of cheeriojs/cheerio@a1be131f9b (2026-08-28).
Data as JSON: /api/errors/164202391ee4c6cb.
Report an issue: GitHub.