issue with macro expansion

Your \map command has one argument delimited by \par.

When you do

\interviewstart
I: I have a question ...

L: Of course I will answer ...
\interviewstop % line 21

\end{document}

the macro \interviewstart is replaced by

\linenumbers\let\do\speakify\map

and the argument to \map is taken to be

I: I have a question ...

Since I is not equal to \endmap, the false branch is followed, eventually leading to another \map macro.

What happens now is that the argument to \map is

L: Of course I will answer ... \interviewstop

because TeX doesn't expand tokens when absorbing macros and the blank line before \end{document} provides the \par delimiter.

Again, L is not \endmap, so the false branch is followed and in the course of expanding the tokens TeX comes to \interviewstop, whose replacement text contains \endmap, which is not defined.

When you have the explicit \par\endmap\par\nolinenumbers, there is no problem, because the first \par is the argument delimiter and the next \map command will absorb \endmap as its argument. Since you compare two undefined tokens, the true branch is followed, leading to a happy end.

What you have to do is to absorb the whole text from \interviewstart to \interviewstop and then do the work on the absorbed tokens.

\documentclass{article}
\usepackage[left]{lineno}

\def\speakify#1: #2\par{\textit{#1}: #2\par}

\long\def\map#1\par{%
  \ifx\interviewstart#1%
  \else
    \speakify#1\par
    \expandafter\map
  \fi
}
\long\def\interviewstart#1\interviewstop{%
  \linenumbers
  \map#1\par\interviewstart\par
  \nolinenumbers
}

\begin{document}

\interviewstart
I: I have a question ...

L: Of course I will answer ...
\interviewstop

\end{document}

enter image description here

This version allows any number of blank lines

\documentclass{article}
\usepackage[left]{lineno}

\def\speakify#1: #2\par{\textit{#1}: #2\par}

\long\def\map#1\par{%
  \ifx\hfuzz#1\hfuzz
    \let\next\map
  \else
    \ifx\interviewstart#1%
      \let\next\relax
    \else
      \speakify#1\par
      \let\next\map
    \fi
  \fi
  \next
}
\long\def\interviewstart#1\interviewstop{%
  \linenumbers
  \map#1\par\interviewstart\par
  \nolinenumbers
}

\begin{document}

\interviewstart
I: I have a question ...


L: Of course I will answer ...

\interviewstop

\end{document}

An environment is, however, much better.

\documentclass{article}
\usepackage[left]{lineno}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentEnvironment{interview}{m}
 {
  \par
  \linenumbers
  \keys_set:nn { hkbst/interview } { #1 }
 }
 {
  \par
 }

\NewDocumentCommand{\Q}{}{\par\textit{\l_hkbst_questioner_tl}:~}

\NewDocumentCommand{\A}{}{\par\textit{\l_hkbst_answerer_tl}:~}

\keys_define:nn { hkbst/interview }
 {
  q .tl_set:N = \l_hkbst_questioner_tl,
  a .tl_set:N = \l_hkbst_answerer_tl,
 }
\ExplSyntaxOff

\begin{document}

\begin{interview}{q=I,a=L}
\Q I have a question ...


\A Of course I will answer ...

\end{interview}

\end{document}

The normal latex syntax for this would be an environment:

enter image description here

\documentclass{article}
\usepackage[]{a4wide}
\usepackage[left]{lineno}


\newenvironment{interview}{\linenumbers\everypar{\additalic}}{\par}
\def\additalic#1:{\textit{#1}:}

\begin{document}


\begin{interview}
I: I have a question for you that I would really like to know the answer to. Could you please explain it in your own words while the moon is still high in the sky? That would be lovely thank you very much!

L: Of course I will answer gladly all questions you might have no matter how silly I feel they may be provided payment is made in full before commencement of the answering phase.
\end{interview}

\end{document}

Actually I would have used a syntax such as

\item[L] I have a question....

then you would not have needed any low level delimited macros or \everpar tricks.


In comments you ask for a variant that sets the paragraph in italic and the label in bold.

\newenvironment{interview}{\linenumbers\itshape\everypar{\additalic}}{\par}
\def\additalic#1:{\textup{\textbf{#1}}:}