Undefined color with the \colorlet command

You can use \globalcolorstrue to make the color definitions global.

But I would avoid to test all the time the argument and reset colors. I would define them first and use them by name:

\documentclass[letterpaper,10pt]{article}
\usepackage[english,german]{babel}
\usepackage{xcolor}
\usepackage{boolexpr,pdftexcmds,trace}

\definecolor{mediumtealblue}{rgb}{0.0, 0.33, 0.71}
\definecolor{red(munsell)}{rgb}{0.95, 0.0, 0.24}
\definecolor{forestgreen}{rgb}{0.13, 0.55, 0.13}
\definecolor{ginger}{rgb}{0.69, 0.4, 0.0}


\colorlet{dernouncolor}{mediumtealblue}
\colorlet{dienouncolor}{red(munsell)}
\colorlet{dasnouncolor}{forestgreen}

\providecommand{\denoun}[3][---]{%
    \xglobal\providecolor{#1nouncolor}{named}{black}%
    \textcolor{#1nouncolor}{#1 #2} & \colorbox{#1nouncolor}{\textcolor{white}{die #3}} 
    \\%
}

\begin{document}

    \begin{tabular}{|c|c|}
        \hline
            \multicolumn{2}{|c|}{Nouns in german} \\
        \hline
            \denoun[der]{Apfel}{Äpfel}
            \denoun[die]{Katze}{Katzen}
            \denoun[das]{Beispiel}{Beispiele}
            \denoun[blub]{Beispiel}{Beispiele}
        \hline
    \end{tabular}

\end{document}

enter image description here


The problem is that the \switch gets lost once the & is reached, because each tabular cell is conceived in its own group. The solution is to globally define the \switch (which I do in \getnouncolor), and invoke it in each cell, as needed.

\documentclass[letterpaper,10pt]{article}
\usepackage[english,german]{babel}
\usepackage{xcolor}
\usepackage{boolexpr,pdftexcmds,trace}

\definecolor{mediumtealblue}{rgb}{0.0, 0.33, 0.71}
\definecolor{red(munsell)}{rgb}{0.95, 0.0, 0.24}
\definecolor{forestgreen}{rgb}{0.13, 0.55, 0.13}
\definecolor{ginger}{rgb}{0.69, 0.4, 0.0}

\makeatletter
    \long\def\isequal#1#2{\pdf@strcmp{#1}{#2}}
\makeatother

\providecommand{\denoun}[3][---]{%
    \gdef\getnouncolor{%
    \def\Artikel{#1}%
    \switch%
        \case{\isequal{\Artikel}{der}}%
            \colorlet{nouncolor}{mediumtealblue}%
        \case{\isequal{\Artikel}{die}}%
            \colorlet{nouncolor}{red(munsell)}%
        \case{\isequal{\Artikel}{das}}%
            \colorlet{nouncolor}{forestgreen}%
        \otherwise%
            \colorlet{nouncolor}{black}%
    \endswitch%
    }
    \getnouncolor\textcolor{nouncolor}{#1 #2} & 
    \getnouncolor\colorbox{nouncolor}{\textcolor{white}{die #3}} \\%
}

\begin{document}

    \begin{tabular}{|c|c|}
        \hline
            \multicolumn{2}{|c|}{Nouns in german} \\
        \hline
            \denoun[der]{Apfel}{Äpfel}
            \denoun[die]{Katze}{Katzen}
            \denoun[das]{Beispiel}{Beispiele}
        \hline
    \end{tabular}
    
\end{document}

enter image description here


There's a much simpler solution, without case switch (well, we need to cope with just two cases): make the argument part of the color name.

\documentclass[letterpaper,10pt]{article}
\usepackage[T1]{fontenc}
\usepackage[english,german]{babel}
\usepackage{xcolor}
\usepackage{etoolbox}

\definecolor{mediumtealblue}{rgb}{0.0, 0.33, 0.71}
\definecolor{red(munsell)}{rgb}{0.95, 0.0, 0.24}
\definecolor{forestgreen}{rgb}{0.13, 0.55, 0.13}
\definecolor{ginger}{rgb}{0.69, 0.4, 0.0}
\colorlet{dercolor}{mediumtealblue}
\colorlet{diecolor}{red(munsell)}
\colorlet{dascolor}{forestgreen}
\colorlet{---color}{black}

\newcommand{\denoun}[3][---]{%
  \textcolor{#1color}{#1 #2} &
  \maybecolorbox{#1}{#3\vphantom{Äp}} \\
}
\newcommand{\maybecolorbox}[2]{%
  \ifstrequal{#1}{---}{#2}{\colorbox{#1color}{\textcolor{black}{#2}}}%
}

\begin{document}

\begin{tabular}{|c|c|}
\hline
\multicolumn{2}{|c|}{Nouns in german} \\
\hline
\denoun[der]{Apfel}{Äpfel}
\denoun[die]{Katze}{Katzen}
\denoun[das]{Beispiel}{Beispiele}
\denoun{Foo}{Foo}
\hline
\end{tabular}
    
\end{document}

enter image description here