{"record":{"id":"9cfd25d4d78bcc8f","repo":"nexu-io/open-design","slug":"unsupported-message-line-shape-line","errorCode":null,"errorMessage":"Unsupported message line shape: {line}","messagePattern":"Unsupported message line shape: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/chat-motion-overlay/scripts/build_chat_overlay_spec.py","lineNumber":99,"sourceCode":"    if len(parts) == 3:\n        if is_flag(parts[2]):\n            result[\"text\"] = parts[1]\n            result[\"highlight\"] = True\n            return result\n        if is_side(parts[1]):\n            result[\"side\"] = SIDE_MAP[parts[1]]\n            result[\"text\"] = parts[2]\n            return result\n        result[\"text\"] = parts[1]\n        result[\"avatar\"] = parts[2]\n        return result\n    if len(parts) >= 4 and is_side(parts[1]):\n        result[\"side\"] = SIDE_MAP[parts[1]]\n        result[\"avatar\"] = parts[2]\n        result[\"text\"] = parts[3]\n        result[\"highlight\"] = len(parts) > 4 and is_flag(parts[4])\n        return result\n    raise ValueError(f\"Unsupported message line shape: {line}\")\n\n\ndef is_side(value: str) -> bool:\n    return value in SIDE_MAP\n\n\ndef is_flag(value: str) -> bool:\n    return value.strip().lower() == \"highlight\"\n\n\ndef load_config(path: str | None) -> dict:\n    config = json.loads(json.dumps(DEFAULT_CONFIG))\n    if not path:\n        validate_config(config)\n        return config\n    user = json.loads(Path(path).read_text(encoding=\"utf-8\"))\n    config.update(user)\n    validate_config(config)","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/chat-motion-overlay/scripts/build_chat_overlay_spec.py#L81-L117","documentation":"Raised by parse_message_line in build_chat_overlay_spec.py after the speaker:text regex fallback has been exhausted for '|' delimited lines. The function accepts specific shapes only: 2 parts (speaker|text or speaker|side with side lookup), 3 parts (speaker|side|text, speaker|text|highlight, or speaker|text|avatar), and 4+ parts where parts[1] is a valid side. Any other combination — e.g. 4+ parts where parts[1] is not a side — falls through to ValueError.","triggerScenarios":"A '|' delimited line whose segments do not fit any accepted shape: 4+ parts where the second segment is not a recognized side token (left/right/左/右), e.g. `Alice | extra | more | text`; or a line mixing avatar and side fields in an unsupported order.","commonSituations":"User invents an extended syntax (speaker|side|avatar|text|highlight) but puts fields in the wrong order; copy-paste from a spreadsheet adding extra columns; non-side value landing in the side slot; mixing the 3-part and 4-part grammars inconsistently within one transcript.","solutions":["For 4-field lines, use the supported order `Speaker | side | avatar | text` (plus optional `highlight` as 5th), where side is one of left/right/左/右.","Drop extra '|' columns so the line collapses to 2 or 3 parts (the most permissive shapes).","Verify each segment: side must be in {left,right,左,右}; a flag segment must be the literal 'highlight'.","If you need richer per-message metadata, edit the transcript schema in the script rather than overloading the pipe format."],"exampleFix":"// before\nAlice | top-left | smile.png | hello\n# -> ValueError: Unsupported message line shape: ...\n\n// after (side must be a recognized token)\nAlice | left | smile.png | hello\n# or simpler:\nAlice | hello","handlingStrategy":"validation","validationCode":"SIDE_TOKENS = {\"left\", \"right\", \"左\", \"右\"}\n\ndef message_shape_ok(line: str) -> bool:\n    if \"|\" not in line:\n        return True  # handled by speaker:text regex path\n    parts = [p.strip() for p in line.split(\"|\")]\n    if len(parts) == 2:\n        return True\n    if len(parts) == 3:\n        return True\n    if len(parts) >= 4 and parts[1] in SIDE_TOKENS:\n        return True\n    return False\n\nbad = [ln for ln in lines if \"|\" in ln and not message_shape_ok(ln)]\nif bad:\n    raise SystemExit(f\"Unsupported transcript shapes: {bad[:3]}\")","typeGuard":null,"tryCatchPattern":"try:\n    parsed = parse_transcript(Path(args.input))\nexcept ValueError as exc:\n    raise SystemExit(f\"Transcript parse error at line: {exc}\") from exc","preventionTips":["Standardize on one pipe-delimited shape per project to avoid ambiguity.","For 4+ field lines, always put a valid side token (left/right/左/右) in position 2.","Validate the whole transcript before rendering so all errors surface at once.","Consider migrating richer metadata to the JSON config rather than overloading the pipe grammar."],"tags":["parsing","validation","transcript","chat-overlay"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}