```ts
export function crateOverflowPath(root: Record<string, unknown>): string {
  if (typeof root !== 'object' || root === null) {
    throw new Error('Root must be a mapping');
  }

  const validateCrate = (crate: any, path: string[]): void => {
    if (typeof crate.tag !== 'string' || crate.tag.includes('.') || crate.tag.length === 0) {
      throw new Error(`Invalid tag at ${path.join('.')}`);
    }
    if (!Number.isInteger(crate.weight) || crate.weight < 0) {
      throw new Error(`Invalid weight at ${path.join('.')}`);
    }
    if (!Number.isInteger(crate.cap) || crate.cap <= 0) {
      throw new Error(`Invalid cap at ${path.join('.')}`);
    }
    if (!Array.isArray(crate.inside)) {
      throw new Error(`Invalid inside at ${path.join('.')}`);
    }
  };

  const calculateGross = (crate: any, path: string[]): number => {
    validateCrate(crate, path);
    let gross = crate.weight;
    for (const [index, innerCrate] of crate.inside.entries()) {
      if (typeof innerCrate !== 'object' || innerCrate === null) {
        throw new Error(`Invalid crate inside at ${path.join('.')}`);
      }
      const innerPath = path.concat([String(index)]);
      gross += calculateGross(innerCrate, innerPath);
    }
    return gross;
  };

  const findSpillingCrate = (crate: any, path: string[]): string => {
    validateCrate(crate, path);
    let gross = crate.weight;
    for (const [index, innerCrate] of crate.inside.entries()) {
      if (typeof innerCrate !== 'object' || innerCrate === null) {
        throw new Error(`Invalid crate inside at ${path.join('.')}`);
      }
      const innerPath = path.concat([String(index)]);
      gross += calculateGross(innerCrate, innerPath);
    }
    if (gross > crate.cap) {
      return path.map(tag => String(tag)).join('.');
    }
    for (const [index, innerCrate] of crate.inside.entries()) {
      const result = findSpillingCrate(innerCrate, path.concat([String(index)]));
      if (result) {
        return result;
      }
    }
    return '';
  };

  return findSpillingCrate(root, []);
}
```