```python
from typing import *
from collections import *

def trace_relay(links: dict, start: str) -> list:
    """
    Returns the list of post names visited by a night watch starting at 'start'
    and following the links until reaching the empty name. Raises ValueError for invalid inputs.
    """
    if not isinstance(links, Mapping):
        raise ValueError("links must be a mapping.")
    
    if start not in links or not isinstance(start, str):
        raise ValueError("start must be a valid post name in links.")
    
    visited = set()
    current = start
    path = [current]
    
    while current != "":
        next_post = links.get(current)
        
        if next_post is None:
            raise ValueError(f"Invalid link: {current} -> {next_post}")
        
        if next_post in visited:
            return [start] + list(visited)  # Avoid infinite loop, return unique path up to the cycle
        
        visited.add(next_post)
        current = next_post
        path.append(current)
    
    return path
```