{"id":5315,"date":"2026-08-30T14:50:35","date_gmt":"2026-08-30T05:50:35","guid":{"rendered":"https:\/\/donguri3.net\/server-tech\/narou-rb-download-error-yaml-newline-fix-2\/"},"modified":"2026-08-30T14:50:36","modified_gmt":"2026-08-30T05:50:36","slug":"narou-rb-download-error-yaml-newline-fix","status":"publish","type":"post","link":"https:\/\/donguri3.net\/en\/server-tech\/virtualization-container-wsl\/narou-rb-download-error-yaml-newline-fix\/","title":{"rendered":"\u3010Narou.rb\u3011Was &#8220;Novel has been deleted&#8221; a lie? The real culprit behind the download error was &#8220;just a single line break&#8221;"},"content":{"rendered":"<p>&#8220;Narou.rb&#8221; is a Web novel management tool that I personally love using. Running inside a Docker container, it&#8217;s a reliable partner that automatically collects daily updates and converts them into e-books. However, the other day, when I tried to download a specific new novel, it was stubbornly rejected.<\/p>\n<p>The logs mercilessly displayed the following:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">[ERROR] \u5c0f\u8aac\u304c\u524a\u9664\u3055\u308c\u3066\u3044\u308b\u304b\u975e\u516c\u958b\u306a\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\n[ERROR] https:\/\/ncode.syosetu.com\/n8281jr\/ \u306e\u76ee\u6b21\u30c7\u30fc\u30bf\u304c\u53d6\u5f97\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f<\/pre>\n<p>It would be easy to give up and think, &#8220;Ah, it must have been deleted.&#8221; However, when accessing it via a browser, that novel was actively serialized and doing well. This was a challenge letter from the server. This record details how I tracked down the cause of Narou.rb&#8217;s false positive\u2014thinking it was &#8220;deleted&#8221;\u2014and resolved it by modifying the configuration file (YAML).<\/p>\n<h2>Mission: Clear the False Accusation and Resume Collection<\/h2>\n<p>The objective this time is to &#8220;correctly recognize an existing novel and make the download succeed.&#8221;<\/p>\n<p>In web scraping tools, acquisition failures due to target site design changes or fluctuations in HTML structure are inevitable. However, since the error message stated it was &#8220;deleted,&#8221; the tool judged that &#8220;the page itself could not be found (or could not be parsed).&#8221;<\/p>\n<h3>The goal (quantitative target) is as follows:<\/h3>\n<ol>\n<li>Successful download of the target novel (ID: n8281jr) (100% progress)<\/li>\n<li>Robust configuration that won&#8217;t throw errors even for novels with similar HTML structures in the future<\/li>\n<\/ol>\n<h2>Investigation Begins: Why Is It &#8220;Invisible&#8221;?<\/h2>\n<p>First, I checked the connection from the server (Docker container) to the internet. Using the curl command, I tried accessing Narou&#8217;s server directly from inside the container.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">docker-compose exec narou curl -I https:\/\/ncode.syosetu.com\/n8281jr\/<\/pre>\n<p>The result was HTTP\/1.1 200 OK. There were no problems with the communication path, and it was not blocked by a WAF (firewall) like Cloudflare. In other words, the HTML data had arrived safely.<\/p>\n<p>The fact that data arrived yet could not be &#8220;acquired&#8221; means that the &#8220;map for page analysis (regular expressions)&#8221; held by Narou.rb and the actual &#8220;terrain (HTML)&#8221; were mismatched.<\/p>\n<h2>Suspects Under Investigation<\/h2>\n<p>At first, I suspected changes in the format of the table of contents list or update dates. Were there line breaks next to the dates? Did the tag class names change? I carefully reviewed subtitles (table of contents definition) and nu (update date definition) in the configuration file (ncode.syosetu.com.yaml), but lacked a smoking gun.<\/p>\n<p>However, light shines nearest the candlestick. The parsing failed at the most fundamental part: the &#8220;title.&#8221;<\/p>\n<h3>Solution: The Pitfall Called Line Breaks<\/h3>\n<p>In Narou.rb&#8217;s configuration file (YAML), the rule for fetching titles was written as follows:<\/p>\n<h3>Before Modification (Problematic Description)<\/h3>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\"># \u30bf\u30a4\u30c8\u30eb\nt: &lt;h1 class=&quot;p-infotop-title&quot;&gt;&lt;a href=&quot;.+?&quot;&gt;(?&lt;title&gt;.+?)&lt;\/a&gt;&lt;\/h1&gt;<\/pre>\n<p>As a regular expression, this expects that &#8220;everything from the h1 tag to the closing a tag is connected in a single line.&#8221; This is because the dot (.) in regular expressions normally only matches &#8220;any character except a line break.&#8221;<\/p>\n<p>However, when I checked the HTML source of the novel that failed to download this time, it looked like this:<\/p>\n<h3>Actual HTML<\/h3>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">&lt;h1 class=&quot;p-infotop-title&quot;&gt;\n&lt;a href=&quot;...&quot;&gt;\n\u5d29\u58ca\u4e16\u754c\u306e\u9b54\u6cd5\u6756\u8077\u4eba\n&lt;\/a&gt;\n&lt;\/h1&gt;<\/pre>\n<p>There are line breaks between the h1 and a tags, and before and after the title. Because of this &#8220;single line break,&#8221; the regular expression above (.+?) failed to match, leading Narou.rb to the false conclusion that &#8220;title not found = this is not a novel page = it must have been deleted.&#8221;<\/p>\n<h3>Applying the Patch<\/h3>\n<p>Once the cause is known, fixing it is easy. We just need to make the YAML description support &#8220;multiple lines (line breaks).&#8221; Using the volumes feature of docker-compose, we mount the modified YAML file into the container.<\/p>\n<h3>After Modification (Fixed YAML)<\/h3>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\"># \u30bf\u30a4\u30c8\u30eb\n# |- \u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u6539\u884c\u3092\u542b\u3093\u3060\u6587\u5b57\u5217\u3068\u3057\u3066\u5b9a\u7fa9\u3059\u308b\nt: |-\n&lt;h1 class=&quot;p-infotop-title&quot;&gt;\n&lt;a href=&quot;.+?&quot;&gt;(?&lt;title&gt;.+?)&lt;\/a&gt;\n&lt;\/h1&gt;<\/pre>\n<p>By inserting line breaks to match the HTML structure (or using a regular expression containing line breaks like [\\s\\S]+?), the parser can now correctly recognize the title.<\/p>\n<p>Applying this modified file, I executed the download command again.<\/p>\n<p><pre class=\"brush: bash; title: ; notranslate\" title=\"\">docker-compose exec narou narou download n8281jr<\/pre>\n<\/p>\n<p>As a result, as if to belie its previous stubborn rejections, the download progress bar began to run.<\/p>\n<h2>Summary from Nando Kobo<\/h2>\n<p>This trouble was not a system bug, but a collision between &#8220;overly strict definitions&#8221; and &#8220;HTML fluctuations.&#8221;<\/p>\n<ol>\n<li>Doubt error logs: Even if told &#8220;it has been deleted,&#8221; first verify its existence using a browser and curl.<\/li>\n<li>The trap of regular expressions: The . (dot) is not almighty. In HTML parsing, &#8220;line breaks&#8221; can always become an enemy.<\/li>\n<li>YAML flexibility: By slightly rewriting the definition file, the tool springs back to life.<\/li>\n<\/ol>\n<p>Even on a narrow server like a walk-in closet (Nando), a comfortable reading environment is maintained by accumulating such small &#8220;repairs.&#8221; If you ever encounter a phenomenon where &#8220;only a certain novel won&#8217;t download,&#8221; please definitely suspect the &#8220;regular expression around the title&#8221; in the definition file.<\/p>\n<p>Wishing you a good server life.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;Narou.rb&#8221; is a Web novel management tool that I personally love using. Running inside a Docker co [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":2582,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"en_US","_original_post":"https:\/\/donguri3.net\/?p=2580","footnotes":""},"categories":[1171],"tags":[118,18,19,52,291,10,381,397,1042],"class_list":["post-5315","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-virtualization-container-wsl","tag-cloudflare","tag-docker","tag-docker-compose","tag-https","tag-yaml","tag-server","tag-381","tag-397","tag-1042","en-US"],"_links":{"self":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/comments?post=5315"}],"version-history":[{"count":1,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5315\/revisions"}],"predecessor-version":[{"id":5318,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5315\/revisions\/5318"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media\/2582"}],"wp:attachment":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media?parent=5315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/categories?post=5315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/tags?post=5315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}