eyaltoledano/claude-task-master · error · Error

Payload must be an object

Error message

Payload must be an object

What it means

createRow() is a convenience wrapper around createBar() for data rows in the progress tracker UI. It validates that the payload holding the row's data exists and is an object before delegating to createBar. Passing null, undefined, or a primitive is rejected because the bar renderer needs to read named fields from the payload object.

Source

Thrown at src/progress/tracker-ui.js:52

		bar.update(1, payload);
		return bar;
	}

	/**
	 * Creates a header with borders
	 */
	createHeader(headerFormat, borderFormat) {
		this.createBar(borderFormat); // Top border
		this.createBar(headerFormat); // Header
		this.createBar(borderFormat); // Bottom border
	}

	/**
	 * Creates a data row
	 */
	createRow(rowFormat, payload) {
		if (!payload || typeof payload !== 'object') {
			throw new Error('Payload must be an object');
		}
		return this.createBar(rowFormat, payload);
	}

	/**
	 * Creates a border element
	 */
	createBorder(borderFormat) {
		return this.createBar(borderFormat);
	}
}

/**
 * Creates a bordered header for progress tables.
 * @param {Object} multibar - The multibar instance.
 * @param {string} headerFormat - Format string for the header row.
 * @param {string} borderFormat - Format string for the top and bottom borders.
 * @returns {void}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Ensure the payload is a non-null object before calling createRow (e.g. const payload = row?.data ?? {}).
  2. If the row should be optional, check the data first and skip the row instead of passing null.
  3. Call the higher-level helpers createProgressRow/addTaskRow/addSummaryRow, which construct valid payloads.
  4. Log the payload with console.log(JSON.stringify(payload)) to spot where it became null.

Example fix

// before
const row = tasks.find(t => t.id === id);
tracker.createRow(rowFormat, row?.data);
// after
const row = tasks.find(t => t.id === id);
if (row?.data) {
  tracker.createRow(rowFormat, row.data);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function isValidPayload(p) {
  return p !== null && typeof p === 'object';
}
// usage
if (!isValidPayload(payload)) throw new Error('createRow payload must be a non-null object');
tracker.createRow(rowFormat, payload);

Type guard

const isRowPayload = (p) => p !== null && typeof p === 'object';

Try / catch

try {
  tracker.createRow(rowFormat, payload);
} catch (err) {
  if (err.message === 'Payload must be an object') {
    console.error('Row payload invalid:', payload);
    return; // skip row or substitute defaults
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling tracker.createRow(rowFormat, null), createRow(rowFormat, undefined), createRow(rowFormat, 'string'), createRow(rowFormat, 42), or forgetting the payload argument entirely.

Common situations: Building row data dynamically where a lookup returns null/undefined before the row is created; spreads on a possibly-undefined object like {...maybeData} evaluated before a null check; calling the lower-level createRow API directly instead of createProgressRow/addTaskRow/addSummaryRow helpers which build the payload for you.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/288a278c10041fb6. Report an issue: GitHub.