{"record":{"id":"4602457e9d9adad4","repo":"Zie619/n8n-workflows","slug":"failed-to-convert-start-time-reason-startdttar","errorCode":null,"errorMessage":"Failed to convert start time. Reason: ${startDtTargetZone.invalidReason || 'Unknown'}","messagePattern":"Failed to convert start time\\. Reason: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"workflows/Webhook/0829_Webhook_Code_Create_Webhook.json","lineNumber":1251,"sourceCode":"              \"type\": \"string\",\n              \"value\": \"={{ $json.body.message.call.customer.number }}\"\n            }\n          ]\n        }\n      },\n      \"typeVersion\": 3.3,\n      \"notes\": \"This set node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"b4bc5cee-d631-4aa8-a3ff-59a0b647d36a\",\n      \"name\": \"Convert time to CST America / Chicago\",\n      \"type\": \"n8n-nodes-base.code\",\n      \"position\": [\n        1480,\n        1580\n      ],\n      \"parameters\": {\n        \"jsCode\": \"// Get all input items\\nconst items = $input.all();\\n\\n// Loop through each item\\nfor (const item of items) {\\n  // Get the values from the current item's JSON data\\n  const startTimeUTC = item.json.starttime;\\n  const endTimeUTC = item.json.endtime;\\n  const targetTimeZone = item.json.timeZone; // e.g., \\\"America/Chicago\\\"\\n\\n  // Basic validation: ensure the necessary fields exist\\n  if (!startTimeUTC || !endTimeUTC || !targetTimeZone) {\\n    console.warn(`Skipping item due to missing time data or timezone. Item JSON: ${JSON.stringify(item.json)}`);\\n    item.json.conversionError = \\\"Missing starttime, endtime, or timeZone\\\";\\n    continue; // Move to the next item\\n  }\\n\\n  try {\\n    // --- Start Time Conversion ---\\n    // Parse the original UTC ISO string using Luxon (NO $ prefix)\\n    const startDt = luxon.DateTime.fromISO(startTimeUTC, { zone: 'utc' });\\n\\n    // Convert the DateTime object to the target timezone\\n    const startDtTargetZone = startDt.setZone(targetTimeZone);\\n\\n    // Check if the conversion was valid\\n    if (!startDtTargetZone.isValid) {\\n      throw new Error(`Failed to convert start time. Reason: ${startDtTargetZone.invalidReason || 'Unknown'}`);\\n    }\\n\\n    // Format the result back into an ISO string with the correct offset\\n    item.json.starttime = startDtTargetZone.toISO();\\n\\n    // --- End Time Conversion ---\\n    // Parse the original UTC ISO string using Luxon (NO $ prefix)\\n    const endDt = luxon.DateTime.fromISO(endTimeUTC, { zone: 'utc' });\\n\\n    // Convert the DateTime object to the target timezone\\n    const endDtTargetZone = endDt.setZone(targetTimeZone);\\n\\n     // Check if the conversion was valid\\n    if (!endDtTargetZone.isValid) {\\n      throw new Error(`Failed to convert end time. Reason: ${endDtTargetZone.invalidReason || 'Unknown'}`);\\n    }\\n\\n    // Format the result back into an ISO string with the correct offset\\n    item.json.endtime = endDtTargetZone.toISO();\\n\\n    // Optionally remove the error flag if conversion was successful this time\\n    delete item.json.conversionError;\\n\\n  } catch (error) {\\n    console.error(`Error converting time for item: ${JSON.stringify(item.json)}. Error: ${error.message}`);\\n    // Add/update the error flag to the item's JSON\\n    item.json.conversionError = error.message;\\n  }\\n}\\n// Return the modified array of items\\nreturn items;\"\n      },\n      \"typeVersion\": 2,\n      \"notes\": \"This code node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"2c8b2884-14d3-4bd4-92d8-6e402ca3a8de\",\n      \"name\": \"Create Event\",\n      \"type\": \"n8n-nodes-base.googleCalendar\",\n      \"onError\": \"continueErrorOutput\",\n      \"position\": [\n        1700,\n        1580\n      ],\n      \"parameters\": {\n        \"end\": \"={{ $json.endtime }}\",\n        \"start\": \"={{ $json.starttime }}\",\n        \"calendar\": {\n          \"__rl\": true,","sourceCodeStart":1233,"sourceCodeEnd":1269,"githubUrl":"https://github.com/Zie619/n8n-workflows/blob/94007c1445d9258a7da116646b79473e7c7c3282/workflows/Webhook/0829_Webhook_Code_Create_Webhook.json#L1233-L1269","documentation":"Produced in 'Convert time to CST America / Chicago' when Luxon's DateTime.fromISO(starttime, {zone:'utc'}).setZone(timeZone) yields an invalid DateTime (isValid false, e.g. invalidReason 'bad input format' or 'unsupported zone'). Important: this throw is INSIDE the node's try/catch, which catches it and writes item.json.conversionError = error.message — so it does not fail the workflow; the message surfaces as a per-item error flag consumed downstream.","triggerScenarios":"starttime/endtime not a valid ISO 8601 string (e.g., '2024-03-01 14:00' without seconds/zone, an epoch number, an Excel serial), or timeZone not a valid IANA name ('CST', 'America/ Chicago', empty). The earlier missing-fields check already flags absent values via conversionError + continue.","commonSituations":"Source systems emitting non-ISO datetimes (spreadsheets, legacy APIs), users typing 'CST'/'CDT' abbreviations instead of 'America/Chicago', or timezone strings with whitespace/typos. Downstream nodes must handle items carrying conversionError, otherwise 'Create Event' receives garbage times.","solutions":["Log conversionError items: their message names the Luxon invalidReason; fix the source to emit full ISO 8601 UTC strings (e.g., 2024-03-01T14:00:00Z).","Normalize before parsing: if starttime is a number, treat it as epoch ms (DateTime.fromMillis); if it lacks zone info, append 'Z' or use {zone:'utc'} deliberately.","Validate timeZone against a known IANA list or intercept common aliases (CST->America/Chicago) before setZone.","Add a Filter/IF after this node to route conversionError items to a review path instead of letting them reach Google Calendar."],"exampleFix":"// before\nconst startDt = luxon.DateTime.fromISO(startTimeUTC, { zone: 'utc' });\nconst startDtTargetZone = startDt.setZone(targetTimeZone);\nif (!startDtTargetZone.isValid) {\n  throw new Error(`Failed to convert start time. Reason: ${startDtTargetZone.invalidReason || 'Unknown'}`);\n}\n\n// after - normalize common inputs first\nconst zoneAliases = { CST: 'America/Chicago', CDT: 'America/Chicago', EST: 'America/New York' };\nconst tz = zoneAliases[targetTimeZone] || targetTimeZone.trim();\nlet startDt = luxon.DateTime.fromISO(String(startTimeUTC), { zone: 'utc' });\nif (!startDt.isValid && typeof startTimeUTC === 'number') {\n  startDt = luxon.DateTime.fromMillis(startTimeUTC);\n}\nconst startDtTargetZone = startDt.setZone(tz);\nif (!startDtTargetZone.isValid) {\n  item.json.conversionError = `Failed to convert start time (${startTimeUTC}) to ${tz}: ${startDtTargetZone.invalidReason}`;\n  continue;\n}","handlingStrategy":"fallback","validationCode":"const isValidIso = (s) => typeof s === 'string' && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$/.test(s);\nconst zoneAliases = { CST: 'America/Chicago', CDT: 'America/Chicago' };\nconst tz = zoneAliases[targetTimeZone] || String(targetTimeZone || '').trim();\nif (!isValidIso(startTimeUTC) || !isValidIso(endTimeUTC)) {\n  item.json.conversionError = `Non-ISO datetime: start=${startTimeUTC}, end=${endTimeUTC}`;\n  continue;\n}","typeGuard":"const isIanaZone = (z) =>\n  typeof z === 'string' && /^(Africa|America|Antarctica|Asia|Atlantic|Australia|Europe|Indian|Pacific|Etc)\\//.test(z) || z === 'UTC';","tryCatchPattern":"try {\n  item.json.starttime = luxon.DateTime.fromISO(startTimeUTC, { zone: 'utc' }).setZone(tz).toISO();\n  item.json.endtime = luxon.DateTime.fromISO(endTimeUTC, { zone: 'utc' }).setZone(tz).toISO();\n  delete item.json.conversionError;\n} catch (e) {\n  item.json.conversionError = e.message; // per-item flag, workflow continues\n}","preventionTips":["Require full ISO 8601 UTC strings from source systems; validate them at ingestion, not mid-workflow.","Maintain an alias table for user-supplied zones (CST/EST) instead of passing them to setZone raw.","Add a Filter after this node so conversionError items never reach the calendar-write node."],"tags":["n8n","code-node","luxon","datetime","timezone","google-calendar","data-quality"],"backgroundTag":null,"analyzedSha":"94007c1445d9258a7da116646b79473e7c7c3282","analyzedAt":"2026-08-15T04:10:37.591Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}