Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix the YAML syntax error: did not find expected '-' indicator while parsing a block?

I have some code written in my .travis.yml written for a Python library. Using lint.travis-ci.org, I came to know that there is some indentation problem in my YAML file. Here is the part which the error points to

install:    - if [[ "${TEST_PY3}" == "false" ]]; then       pip install Cython;       python setup.py build; # To build networkx-metis       mkdir core; # For the installation of networkx core       cd core;       git clone https://github.com/orkohunter/networkx.git;       cd networkx/;       git checkout addons;       python setup.py install;       cd ..;     fi 

Where am I wrong? The error says

syntax error: (<unknown>): did not find expected '-' indicator while parsing a block collection at line 32 column 3 

It would be great if there were a tool like autopep8 to fix the indentation of YAML files.

like image 839
Himanshu Mishra Avatar asked Jun 28 '15 21:06

Himanshu Mishra


People also ask

Did not find expected'-'indicator while parsing a block?

So, check that you don't have any spaces in front of “– name:” at any point in your . yml file, as that could be one of the solutions for why the “Did not find expected '-' indicator while parsing a block collection” error was thrown.

Could not find expected in Yaml?

To resolve this issue, delete extra spaces after the colon ':' in the yml file. Ensure all the name:value pairs have only one space after the colon. Correct the yml file and restart the elastic search server.

What is Yaml syntax?

YAML syntaxYAML has features that come from Perl, C, XML, HTML, and other programming languages. YAML is also a superset of JSON, so JSON files are valid in YAML. YAML uses Python-style indentation to indicate nesting. Tab characters are not allowed, so whitespaces are used instead.

What is a Yaml file?

YAML is a digestible data serialization language often used to create configuration files with any programming language. Designed for human interaction, YAML is a strict superset of JSON, another data serialization language. But because it's a strict superset, it can do everything that JSON can and more.


2 Answers

You don't have 32 lines in your file (probably because you stripped non-essential data out of the example), but the indentation level points to the line with fi.

Actually the problem starts earlier and what you want to do is specify the action to take as a multi-line string. You can specify those in YAML in multiple ways but the cleanest is to use the literal scalar indicator "|", which preserves newlines:

install:    - |     if [[ "${TEST_PY3}" == "false" ]]; then       pip install Cython;       python setup.py build; # To build networkx-metis       mkdir core; # For the installation of networkx core       cd core;       git clone https://github.com/orkohunter/networkx.git;       cd networkx/;       git checkout addons;       python setup.py install;       cd ..;     fi 

There is no automatic YAML re-indentation tool for these kind of errors.

Reindenters for Python take working code and make the indentation consistent (replacing TABs, always same indent per level). Python code re-indentation on code with syntax errors, either doesn't work or might produce non-correct results.

Reindenters for YAML face the same problem: what to do if the input doesn't make sense (and what is clear to you and me, is not always clear to a program). Just making everything that doesn't parse well into a multi-line scalar is not a generic solution.

Apart from that, most YAML parsers throw away some information on reading in the files, that you would not want to get lost by re-indenting, including EOL comments, hand crafted anchor names, mapping key ordering, etc. All without violating the requirements in the specification.

If you want to uniformly indent your (correct) YAML you can use the yaml utility that is part of the [ruamel.yaml][2] package (disclaimer: I am the author of that package). Your original input used with yaml round-trip .travis.yml would give:

 ...   in "<byte string>", line 3, column 3:       - if [[ "${TEST_PY3}" == "false" ...        ^ expected <block end>, but found '<scalar>'   in "<byte string>", line 6, column 7:           mkdir core; # For the installati ... 

Unfortunately not much more helpful in finding the error, the correct .travis.yml version run through yaml round-trip .travis.yml will tell you that it stabilizes on the second round-trip (ie. on the first the extra whitespace is lost). And yaml round-trip .travis.yml --save gives you:

install: - |   if [[ "${TEST_PY3}" == "false" ]]; then     pip install Cython;     python setup.py build; # To build networkx-metis     mkdir core; # For the installation of networkx core     cd core;     git clone https://github.com/orkohunter/networkx.git;     cd networkx/;     git checkout addons;     python setup.py install;     cd ..;   fi 

Please note that in this # TO build networkx-metis is not a YAML comment. It is just part of the multi-line string. A comment on a line before the first or after the last would however be preserved.

like image 104
Anthon Avatar answered Sep 17 '22 12:09

Anthon


The error means you've syntax error and this particular is difficult to track, as it could mean multiple things, wrong indentation, including missing double quote or you need to make sure to double quote some special characters.

In case you keep track of your .travis.yml in git repository, using travis command you can easily check the previous versions and compare.

For example:

$ travis lint <(git show HEAD^:.travis.yml ) Warnings for /dev/fd/63: [x] syntax error: (<unknown>): did not find expected '-' indicator while parsing a block collection at line 61 column 3 $ travis lint <(git show HEAD~2:.travis.yml) Hooray, /dev/fd/63 looks valid :) 

Where HEAD~2 is checking 2 commits behind, so keep increasing the number until it'll work, once found, then compare like:

git diff HEAD~2 .travis.yml 

Otherwise separate into smaller pieces or keep removing some sections until it will work.


Using ruby is alternative way of checking your YAML syntax:

ruby -e "require 'yaml';puts YAML.load_file('.travis.yml')" 

so you don't need POST your code each time via travis which works in similar way as Travis WebLint.


Example

The following syntax is incorrect:

language: python before_script:   - |     true # Some comment.     true 

because comment has wrong indentation as per:

[x] syntax error: (): did not find expected '-' indicator while parsing a block collection at line 3 column 3

Here is valid syntax:

language: python before_script:   - |     true     # Some comment.     true 

The above issue especially happens when editing files in Vim, which is doing indentation of comments making them start from the beginning.

like image 23
kenorb Avatar answered Sep 18 '22 12:09

kenorb