Mysterious 'bad_return' from supervisor

I was recently evaulating this erlang fluentd client and got the following error when running rebar3 ct:

%%% efluentc_SUITE ==> {tc_auto_skip,
 {failed,
  {efluentc_SUITE,init_per_suite,
   {'EXIT',
    {{badmatch,
      {error,
       {efluentc,
        {bad_return,
         {{efluentc_app,start,[normal,[]]},
          {'EXIT',
           {noproc,
            {gen_server,call,[efluentc_sup,{start_child,[0]},infinity]}}}}}}}},

What's a bad_return? It happens when the init/1 function in a supervisor module returns an invalid supervisor spec. Still, the project's Travis page shows the build as green! What gives?

It turns out that while the version of Erlang that I had been running, 17.5, supports maps, it does not support the relatively new map-based supervisor spec API.

This spec was causing the error:

%% Supervisor callbacks
init([]) ->
    SupFlags = #{
      strategy  => simple_one_for_one,
      intensity => 1000,
      period    => 3600
    },

    Child = #{
      id       => 'efluentc_client',
      start    => {'efluentc_client', start_link, []},
      restart  => permanent,
      shutdown => 2000,
      type     => worker,
      modules  => ['efluentc_client']
    },

    {ok, {SupFlags, [Child]}}.

Conclusion

If you're having problems with supervisors crashing with bad_returns, check your Erlang/OTP version. Map-based specs were added in Erlang 18.