{"record":{"id":"a3635a09a90828b6","repo":"jackwener/OpenCLI","slug":"context-row-index-1-is-missing-field","errorCode":null,"errorMessage":"${context} row ${index + 1} is missing ${field}.","messagePattern":"(.+?) row (.+?) is missing (.+?)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/discord-app/utils.js","lineNumber":40,"sourceCode":"    }\n    return value;\n}\n\nfunction requireArrayEvaluateResult(payload, context) {\n    const value = unwrapEvaluateResult(payload);\n    if (!Array.isArray(value)) {\n        throw new CommandExecutionError(`${context} returned malformed browser output.`);\n    }\n    return value;\n}\n\nfunction requireNonEmptyRowField(row, field, context, index) {\n    if (!row || typeof row !== 'object' || Array.isArray(row)) {\n        throw new CommandExecutionError(`${context} returned malformed row ${index + 1}.`);\n    }\n    const value = String(row[field] || '').trim();\n    if (!value) {\n        throw new CommandExecutionError(`${context} row ${index + 1} is missing ${field}.`);\n    }\n    return value;\n}\n\nfunction requireRowsWithFields(rows, fields, context) {\n    rows.forEach((row, index) => {\n        fields.forEach((field) => requireNonEmptyRowField(row, field, context, index));\n    });\n    return rows;\n}\n\nexport function isDiscordSnowflake(value) {\n    return CHANNEL_ID_RE.test(String(value || '').trim());\n}\n\nexport function normalizeDiscordName(value) {\n    return String(value || '')\n        .trim()","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/discord-app/utils.js#L22-L58","documentation":"requireNonEmptyRowField throws CommandExecutionError '<context> row N is missing <field>.' when a scraped row object exists but the required field (e.g. guild_id, channel_id, name) is empty after trimming. The CLI guarantees every returned row has non-empty key columns, so a blank required field is treated as a broken scrape.","triggerScenarios":"A row object returned by a scrape script lacks a required property or has an empty/whitespace value — e.g. Discord rendered a row without an accessible label or ID, or the mapping script reads the wrong attribute yielding ''.","commonSituations":"Discord UI updates renaming data attributes/classes so row fields extract as empty strings; rows for unloaded/lazy entries that have a container but no text; scraping channels or servers with hidden names (aria-label changes).","solutions":["Inspect the failing row's DOM in the automated browser and update the field extraction in the corresponding build*Script in clis/discord-app/utils.js","Add fallback selectors (e.g. textContent, aria-label, data-id) so a missing attribute doesn't blank the field","Re-run after full page load — lazily hydrated rows often populate later","Skip or log rows with missing optional fields instead of failing, if the field is not essential for your use"],"exampleFix":"// row mapping inside the page script\n// before\nname: el.getAttribute('data-name') || '',\n// after\nname: (el.getAttribute('data-name') || el.getAttribute('aria-label') || el.textContent || '').trim(),","handlingStrategy":"validation","validationCode":"function validateRowFields(rows, fields) {\n  rows.forEach((r, i) => fields.forEach(f => {\n    if (!String(r?.[f] || '').trim()) throw new Error(`Row ${i + 1} missing ${f}`);\n  }));\n}","typeGuard":"function hasField(row, field) {\n  return typeof row === 'object' && row !== null && String(row[field] || '').trim().length > 0;\n}","tryCatchPattern":"try {\n  const rows = await discordAppThreads(page, { url });\n} catch (err) {\n  const m = String(err.message).match(/row (\\d+) is missing (\\w+)/);\n  if (m) console.error(`Row ${m[1]} lacked ${m[2]}: update extraction selectors for that field.`);\n  else throw err;\n}","preventionTips":["Provide fallback extraction sources (aria-label, textContent, data-*) for each required field","Verify required attributes still exist after Discord UI updates","Wait for lazy-loaded rows to hydrate before scraping","Trim and normalize field values inside the page script"],"tags":["discord","data-validation","scraping"],"backgroundTag":"malformed-row-data","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}