{"record":{"id":"761d89dec2811f90","repo":"eyaltoledano/claude-task-master","slug":"type-mismatch-in-metadata-field-field-expect","errorCode":null,"errorMessage":"Type mismatch in metadata field \"${field}\": expected ${expectedType}, got ${actualType}. Using default value.","messagePattern":"Type mismatch in metadata field \"(.+?)\": expected (.+?), got (.+?)\\. Using default value\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/tm-core/src/common/mappers/TaskMapper.ts","lineNumber":228,"sourceCode":"\t\tfield: string,\n\t\tdefaultValue: T\n\t): T {\n\t\tif (!metadata || typeof metadata !== 'object') {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tconst value = (metadata as Record<string, unknown>)[field];\n\n\t\tif (value === undefined) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\t// Runtime type validation: ensure value matches the type of defaultValue\n\t\tconst expectedType = typeof defaultValue;\n\t\tconst actualType = typeof value;\n\n\t\tif (expectedType !== actualType) {\n\t\t\tconsole.warn(\n\t\t\t\t`Type mismatch in metadata field \"${field}\": expected ${expectedType}, got ${actualType}. Using default value.`\n\t\t\t);\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\treturn value as T;\n\t}\n\n\t/**\n\t * Safely extracts an optional string field from metadata\n\t */\n\tprivate static extractOptionalString(\n\t\tmetadata: unknown,\n\t\tfield: string\n\t): string | undefined {\n\t\tif (!metadata || typeof metadata !== 'object') {\n\t\t\treturn undefined;\n\t\t}","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/common/mappers/TaskMapper.ts#L210-L246","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the stored metadata value so its JSON type matches the expected type (e.g. 7 not \"7\").","Re-save the affected task through the app so the mapper writes correctly typed values.","Check which writer produced the bad type (older version, script, manual SQL) and update it.","Ignore the warning if falling back to the default is acceptable behavior."],"exampleFix":"// before (DB metadata)\n{ \"estimatedHours\": \"8\" }\n// after\n{ \"estimatedHours\": 8 }","handlingStrategy":"type-guard","validationCode":"function assertMetaType(value, expected) {\n  if (typeof value !== expected)\n    console.warn(`metadata field type mismatch: expected ${expected}, got ${typeof value}`);\n  return typeof value === expected ? value : undefined;\n}\nassertMetaType(task.metadata?.estimatedHours, 'number');","typeGuard":"function isTypedValue<T>(value: unknown, defaultValue: T): value is T {\n  return typeof value === typeof defaultValue;\n}","tryCatchPattern":"null","preventionTips":["Never hand-edit Supabase metadata JSON columns; write through the app/mapper.","Validate metadata payloads before writing them (zod/io-ts schema per field).","Watch for this warning after upgrading tm-core versions — schema types may have changed.","Run a one-time migration script to coerce stringified numbers/booleans to proper JSON types."],"tags":["typescript","type-safety","metadata","data-migration","supabase"],"backgroundTag":"type-mismatch","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}