```ts
export function orderShelfMarks(marks: string[]): string[] {
  if (!Array.isArray(marks) || marks.length === 0) {
    throw new Error("Invalid input: must be a non-empty array of strings.");
  }

  const markPattern = /^([A-Z]{1,3}) (\d{1,4}(\.\d+)?) ([a-z]\d{1,3})$/;

  const parsedMarks = marks.map(mark => {
    const match = mark.match(markPattern);
    if (!match) {
      throw new Error(`Invalid shelf mark: ${mark}`);
    }
    return {
      stack: match[1],
      run: parseFloat(match[2]),
      cutter: match[4]
    };
  });

  const uniqueMarks = new Set(parsedMarks.map(m => JSON.stringify(m)));
  if (uniqueMarks.size !== marks.length) {
    throw new Error("Duplicate shelf marks detected.");
  }

  return parsedMarks.sort((a, b) => {
    if (a.stack !== b.stack) {
      return a.stack.localeCompare(b.stack);
    }
    if (a.run !== b.run) {
      return a.run - b.run;
    }
    const cutterA = a.cutter.match(/^([a-z])(\d{1,3})$/)!;
    const cutterB = b.cutter.match(/^([a-z])(\d{1,3})$/)!;
    if (cutterA[1] !== cutterB[1]) {
      return cutterA[1].localeCompare(cutterB[1]);
    }
    return parseInt(cutterA[2], 10) - parseInt(cutterB[2], 10);
  }).map(m => `${m.stack} ${m.run} ${m.cutter}`);
}
```