eyaltoledano/claude-task-master · warning

Type mismatch in metadata field "${field}": expected ${expec

Error message

Type mismatch in metadata field "${field}": expected ${expectedType}, got ${actualType}. Using default value.

What it means

extractMetadataField reads a typed field from a task's metadata (complexity, dependencies, etc.) and validates at runtime that the stored value's type matches the type of the expected default. When the database holds the value under a different JSON type (e.g. a string where a number is expected), it logs this warning and returns the default instead of the raw value, preventing type errors downstream.

Source

Thrown at packages/tm-core/src/common/mappers/TaskMapper.ts:228

		field: string,
		defaultValue: T
	): T {
		if (!metadata || typeof metadata !== 'object') {
			return defaultValue;
		}

		const value = (metadata as Record<string, unknown>)[field];

		if (value === undefined) {
			return defaultValue;
		}

		// Runtime type validation: ensure value matches the type of defaultValue
		const expectedType = typeof defaultValue;
		const actualType = typeof value;

		if (expectedType !== actualType) {
			console.warn(
				`Type mismatch in metadata field "${field}": expected ${expectedType}, got ${actualType}. Using default value.`
			);
			return defaultValue;
		}

		return value as T;
	}

	/**
	 * Safely extracts an optional string field from metadata
	 */
	private static extractOptionalString(
		metadata: unknown,
		field: string
	): string | undefined {
		if (!metadata || typeof metadata !== 'object') {
			return undefined;
		}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Fix the stored metadata value so its JSON type matches the expected type (e.g. 7 not "7").
  2. Re-save the affected task through the app so the mapper writes correctly typed values.
  3. Check which writer produced the bad type (older version, script, manual SQL) and update it.
  4. Ignore the warning if falling back to the default is acceptable behavior.

Example fix

// before (DB metadata)
{ "estimatedHours": "8" }
// after
{ "estimatedHours": 8 }
Defensive patterns

Strategy: type-guard

Validate before calling

function assertMetaType(value, expected) {
  if (typeof value !== expected)
    console.warn(`metadata field type mismatch: expected ${expected}, got ${typeof value}`);
  return typeof value === expected ? value : undefined;
}
assertMetaType(task.metadata?.estimatedHours, 'number');

Type guard

function isTypedValue<T>(value: unknown, defaultValue: T): value is T {
  return typeof value === typeof defaultValue;
}

Try / catch

null

Prevention

When it happens

Trigger: A metadata field in the Supabase JSON column was written with a mismatched type — e.g. "7" (string) instead of 7 for a numeric field, true stored as "true", or an object where an array was expected.

Common situations: Manual edits to the database; older app versions or external tools writing metadata with different types; JSON round-trips through systems that stringify values; schema version changes in tm-core.

Related errors


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