I think the problem is due to the way in which the \lstKV@OptArg-mechanism of the listings-package is defined:
Using listings 2020/03/24 Version 1.8d, the MWE
\documentclass{article}
\usepackage{listings}
\begin{document}
\begin{lstlisting}[caption={Algorithm [1] - example}]
example
\end{lstlisting}
\end{document}
yields the following output:

The caption-key is defined as follows:
3373 \lst@Key{caption}\relax{\lstKV@OptArg[{#1}]{#1}%
3374 {\def\lst@caption{##2}\def\lst@@caption{##1}}%
3375 \let\lst@title\@empty}
The \lstKV@OptArg-mechanism in turn is defined as follows:
431 \def\lstKV@OptArg[#1]#2#3{%
432 \gdef\@gtempa[##1]##2{#3}\lstKV@OptArg@{#1}#2\@}
433 \def\lstKV@OptArg@#1{\@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[#1]}}
434 \def\lstKV@OptArg@@[#1]#2\@{\@gtempa[#1]{#2}}
Both \lstKV@OptArg@ and \lstKV@OptArg@@ pass arguments to other macros as ]-delimited arguments without taking into account the case of these arguments as well containing that delimiter, which at the time of carrying out these other macros yields erroneous matching-up of argument-delimiters.
If this is taken into account by having \lstKV@OptArg@ and \lstKV@OptArg@@ pass ]-delimited arguments nested between {..}, like in the example
\documentclass{article}
\usepackage{listings}
\makeatletter
\def\lstKV@OptArg@#1{@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[{#1}]}}%
\def\lstKV@OptArg@@[#1]#2@{@gtempa[{#1}]{#2}}%
\makeatother
\begin{document}
\begin{lstlisting}[caption={Algorithm [1] - example}]
example
\end{lstlisting}
\end{document}
, then you get:

{{Algorithm [1] - example}\relax}– user202729 Jan 05 '22 at 14:17