{"record":{"id":"5752a08b94f97394","repo":"jackwener/OpenCLI","slug":"label-must-be-an-ascii-geogebra-label-like-a-b","errorCode":null,"errorMessage":"${label} must be an ASCII GeoGebra label like A, B1, or poly_1","messagePattern":"(.+?) must be an ASCII GeoGebra label like A, B1, or poly_1","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/geogebra/utils.js","lineNumber":28,"sourceCode":"\nconst GEOGEBRA_URL = 'https://www.geogebra.org/geometry';\nconst APPLET_WAIT_MS = 15_000;\n\nexport function unwrapBridgeEnvelope(value) {\n  if (value && typeof value === 'object' && 'data' in value && 'session' in value) {\n    return value.data;\n  }\n  return value;\n}\n\nfunction isPlainObject(value) {\n  return value && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function normalizeLabel(value, label = 'label') {\n  const normalized = String(value ?? '').trim();\n  if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(normalized)) {\n    throw new ArgumentError(`${label} must be an ASCII GeoGebra label like A, B1, or poly_1`);\n  }\n  return normalized;\n}\n\nexport function normalizeLabelList(value, label, min, max = Infinity) {\n  const parts = String(value ?? '').split(',').map(s => s.trim()).filter(Boolean);\n  if (parts.length < min || parts.length > max) {\n    throw new ArgumentError(`${label} must contain ${min === max ? min : `${min}-${max}`} comma-separated labels`);\n  }\n  return parts.map((part, idx) => normalizeLabel(part, `${label}[${idx + 1}]`));\n}\n\nexport function normalizeNumber(value, label, { defaultValue, positive = false } = {}) {\n  const raw = value == null || value === '' ? defaultValue : value;\n  const number = Number(raw);\n  if (!Number.isFinite(number) || (positive && number <= 0)) {\n    throw new ArgumentError(`${label} must be a ${positive ? 'positive ' : ''}finite number`);\n  }","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/geogebra/utils.js#L10-L46","documentation":"An ArgumentError from normalizeLabel: a GeoGebra label must match /^[A-Za-z][A-Za-z0-9_]*$/ — start with a letter, then letters/digits/underscores only. The `label` parameter names which argument failed (e.g. 'name', 'label[1]', 'points[2]'), so you can tell which value in a list was bad.","triggerScenarios":"`geogebra info --name '1A'` (starts with digit), `--name 'my point'` (space), `--name 'A-B'` (hyphen), `--name ''` (empty); also any point/circle helper that calls normalizeLabel with a bad element of a comma list.","commonSituations":"Copying labels with trailing whitespace or quotes; using hyphens from CSS-style naming; numeric-first labels; passing property keys instead of GeoGebra labels.","solutions":["Use a valid label: letter first, then letters/digits/underscores (A, B1, poly_1)","Trim whitespace and surrounding quotes from the value","Rename the object in GeoGebra to a compliant label (e.g. Rename command) and re-run","For lists, fix the specific element indicated by label[N] in the message"],"exampleFix":"// before\nopencli geogebra info --name \"1A\"\n// after\nopencli geogebra info --name \"A1\"","handlingStrategy":"validation","validationCode":"const LABEL_RE = /^[A-Za-z][A-Za-z0-9_]*$/;\nif (!LABEL_RE.test(String(name ?? '').trim())) {\n  throw new Error(`Label \"${name}\" invalid: must start with a letter, then letters/digits/underscores`);\n}","typeGuard":"const isValidGgbLabel = (v) => /^[A-Za-z][A-Za-z0-9_]*$/.test(String(v ?? '').trim());","tryCatchPattern":"try {\n  await run('geogebra', 'info', '--name', label);\n} catch (err) {\n  if (/must be an ASCII GeoGebra label/.test(err.message)) {\n    label = sanitizeLabel(label); // trim quotes/space, fix leading digit\n    return run('geogebra', 'info', '--name', label);\n  }\n  throw err;\n}","preventionTips":["Sanitize labels: trim, strip quotes, ensure letter-first","Use letters, digits, and underscores only — no hyphens or spaces","Check list output for the exact canonical label before passing it"],"tags":["geogebra","label-validation","argument-validation"],"backgroundTag":"invalid-geogebra-label","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}