This is not a bug. It occurs because you are including the line ends in your folded ranges, so for example the start of line 29 is folded away, causing its contents to be added to line 1. You can do this instead:
cm.markText({line: 1, ch: 0}, {line: 28}, {inclusiveRight: true, inclusiveLeft: true, collapsed: true});
This will collapse only the text you actually want to hide. You have to make the mark inclusive on both sides to actually have it hide the line. Also, when I just tested this I noticed a bug that caused codemirror to not update its display in this case. This patch fixes that.