{"record":{"id":"6035cf848a6f7cab","repo":"affaan-m/ECC","slug":"label-must-be-a-non-empty-string","errorCode":null,"errorMessage":"${label} must be a non-empty string.","messagePattern":"(.+?) must be a non-empty string\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":79,"sourceCode":"\nfunction hasUnsafeControlCharacters(value, allowBodyWhitespace = false) {\n  return Array.from(value).some(character => {\n    const codePoint = character.codePointAt(0);\n    const allowedWhitespace = allowBodyWhitespace\n      && (codePoint === 0x09 || codePoint === 0x0a || codePoint === 0x0d);\n    const isControl = (codePoint <= 0x1f && !allowedWhitespace)\n      || (codePoint >= 0x7f && codePoint <= 0x9f);\n    const isBidirectionalFormatting = (\n      (codePoint >= 0x202a && codePoint <= 0x202e)\n      || (codePoint >= 0x2066 && codePoint <= 0x2069)\n    );\n    return isControl || isBidirectionalFormatting;\n  });\n}\n\nfunction asNonEmptyString(value, label, maxChars = 10_000) {\n  if (typeof value !== 'string' || value.trim().length === 0) {\n    throw new Error(`${label} must be a non-empty string.`);\n  }\n  const normalized = value.trim();\n  if (normalized.length > maxChars) {\n    throw new Error(`${label} is too long (maximum ${maxChars} characters).`);\n  }\n  if (hasUnsafeControlCharacters(normalized)) {\n    throw new Error(`${label} must not contain control or bidirectional formatting characters.`);\n  }\n  return normalized;\n}\n\nfunction validateEnum(value, allowed, label) {\n  const normalized = asNonEmptyString(value, label, 64);\n  if (!allowed.includes(normalized)) {\n    throw new Error(`${label} must be one of: ${allowed.join(', ')}.`);\n  }\n  return normalized;\n}","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L61-L97","documentation":"Thrown by asNonEmptyString(), the shared validator used for nearly every memory-vault string field (title, kind, scope, tags, etc.). It rejects values that are not strings or that are empty/whitespace-only after trimming. The label parameter identifies which field failed.","triggerScenarios":"Passing undefined for a required field, an empty string, a number where a string is expected, or a string of only spaces/tabs/newlines.","commonSituations":"Reading frontmatter with a missing key; user input that was not sanitized; a generator that omits optional-looking but required fields.","solutions":["Inspect the label in the error to find which field is empty.","Provide a non-empty trimmed string for that field.","If the field is genuinely optional in your flow, omit it from the memory document rather than passing an empty string."],"exampleFix":"// before\nasNonEmptyString('', 'title');\n// after\nasNonEmptyString('Auth decision for v2 API', 'title');","handlingStrategy":"type-guard","validationCode":"function isNonEmptyString(value) {\n  return typeof value === 'string' && value.trim().length > 0;\n}\nif (!isNonEmptyString(title)) {\n  throw new Error('title is required and must be a non-empty string.');\n}","typeGuard":"function isNonEmptyString(value) {\n  return typeof value === 'string' && value.trim().length > 0;\n}","tryCatchPattern":"try {\n  result = asNonEmptyString(value, label);\n} catch (e) {\n  if (/must be a non-empty string/.test(e.message)) return null; // treat as missing\n  throw e;\n}","preventionTips":["Trim and check user input before submission.","Make required fields explicit in the form/UI so users cannot submit empty.","Differentiate optional (omit key) from required (must be non-empty) in your schema."],"tags":["memory-vault","validation","string","format"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}