I have this in my .zhsrc file:

[[ -n "${key[Home]}"    ]]  && bindkey  "${key[Home]}"    beginning-of-line     

Pressing Home on my keyboard does seem to trigger going to the beggining of line, so it seems to work, however whenever I edit the .zshrc in vim and save it SyntasticCheck zsh reports a "bad substitution" error.

Is this an error on my part or a bug in the syntax checker?

Edit in response to comment:

No I do not get an error when Zsh starts and yes Syntastic checker says the error is on that line.

$ sed -n /Home/l .zshrc
[[ -n "${key[Home]}"    ]]  && bindkey  "${key[Home]}"    beginning-o\

EDIT 2. Output of zsh -vn .zshrc

I cleaned up my .zshrc file to this:

echo OK
[[ -n "${key[Home]}"    ]]  && bindkey  "${key[Home]}"    beginning-of-line
echo OK2

When I start my shell I see both OK and OK2, no errors show. But here's the output of zsh -vn .zshrc

# /etc/zsh/zshenv: system-wide .zshenv file for zsh(1).
# This file is sourced on all invocations of the shell.
# If the -f flag is present or if the NO_RCS option is
# set within this file, all other initialization files
# are skipped.
# This file should contain commands to set the command
# search path, plus other important environment variables.
# This file should not contain commands that produce
# output or assume the shell is attached to a tty.
# Global Order: zshenv, zprofile, zshrc, zlogin

if [[ -z "$PATH" || "$PATH" == "/bin:/usr/bin" ]]
        export PATH="/usr/local/bin:/usr/bin:/bin:/usr/games"
echo OK
[[ -n "${key[Home]}"    ]]  && bindkey  "${key[Home]}"    beginning-of-line
.zshrc:2: bad substitution

Edit 3

Version: zsh 5.0.7 (x86_64-pc-linux-gnu)

  • That line is valid zsh syntax. Probably the error, if any is on some other line. Is it only SyntasticCheck that reports an error, or do you get the error as well when zsh starts? Does it give a line number for the error? Does that point to that very line? Commented Aug 24, 2017 at 13:15
  • You could get that message if there were invisible characters inside those ${...}. What's the output of sed -n /Home/l .zshrc? Commented Aug 24, 2017 at 13:16
  • 1
    AFAICT, syntastic uses zsh -n on the file to check the syntax. Do you get the same error with zsh -n .zshrc? Commented Aug 24, 2017 at 14:40
  • Yes, I do: zsh -n .zshrc \n .zshrc:73: bad substitution Commented Aug 24, 2017 at 14:41
  • And it's OK with zsh .zshrc? What about zsh -vn .zshrc? Is it possible that the parsing of some earlier code relies on some option having been turned on before like extendedglob (which wouldn't be done with zsh -n) Commented Aug 24, 2017 at 14:49

1 Answer 1


That was a bug in some older versions of zsh fixed in 5.1. Changelog:

2015-07-15 Barton E. Schaefer

  • 35799: Src/params.c: with NO_EXEC, parse parameter subscript expressions to correctly balance enclosing braces, but do not perform the subscripting

after it was reported the same day.

With those versions, it can be reproduced with:

$ zsh -nc '${a[1]}'
zsh:1: bad substitution

According to git bisect, the bug was introduced in 2011 in a fix to a similar issue for associative arrays in commit dfc26195c916d54163a3f0dd2eb159db2d974569, starting with version zsh-4.3.12

More generally, zsh -n (or anyshell -n) is quite limited in its ability to lint code as since it's not running the code, it can't do much in areas where the way some code is evaluated depends on some code that was run beforehand.

For instance ${a[1+]} is invalid for an array, but OK for a hash. Without knowing which zsh -n just doesn't complain.

It can also give false positives like in:

alias aslongas=while
aslongas whatever; do

Where it complains about that unexpected do because it has not acknowledged aslongas as an alias for while.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .