Your table is already near the limit of 8060. Adding a BLOB column (as XML type is) requires another 24 bytes and pushes it over this limit. See SQL Server table columns under the hood to understand what happens and get some queries to look at the physical table layout:
select p.index_id, p.partition_number,
pc.leaf_null_bit,
coalesce(cx.name, c.name) as column_name,
pc.partition_column_id,
pc.max_inrow_length,
pc.max_length,
pc.key_ordinal,
pc.leaf_offset,
pc.is_nullable,
pc.is_dropped,
pc.is_uniqueifier,
pc.is_sparse,
pc.is_anti_matter
from sys.system_internals_partitions p
join sys.system_internals_partition_columns pc
on p.partition_id = pc.partition_id
left join sys.index_columns ic
on p.object_id = ic.object_id
and ic.index_id = p.index_id
and ic.index_column_id = pc.partition_column_id
left join sys.columns c
on p.object_id = c.object_id
and ic.column_id = c.column_id
left join sys.columns cx
on p.object_id = cx.object_id
and p.index_id in (0,1)
and pc.partition_column_id = cx.column_id
where p.object_id = object_id('PPHGrader_PreferenceData')
order by index_id, partition_number;
If you're lucky then some of the space is from dropped columns in which case you can rebuild the table to get rid of that space and try again. If really you're using those almost 8060 bytes per row and not have dropped columns taking up space, then you need to reduce the size:
- change fixed length columns CHAR/NCHAR/BINARY to variable length types VARCHAR/NVARCHAR/VARBINARY
- normalize the object model to reduce the number of attributes
- if still in need for more room per-row, use SPARSE columns