deckctl validate checks your config, themes and local sidecars in one go and
exits non-zero if anything is wrong:
deckctl validate # everything
deckctl validate -t config # just config.yaml
deckctl validate -t themes # just themes.yaml
deckctl validate -t sidecar # every sidecar in every local source
Symptom Cause A local directory doesn’t appear It has no deckctl.yaml. Only directories with a sidecar are templates. A GitLab project doesn’t appear The project is archived — archived projects are filtered out. Empty list, no error The group exists but has no (non-archived) projects. 404 Not FoundWrong group path, or the token can’t see the group. GitLab returns 404 for both cases.
Error Meaning 401 UnauthorizedToken is set but invalid or expired 403 ForbiddenToken is valid but lacks a scope — read_api to list, read_repository to download archives warning: env var "X" is not settoken_env points at an unset/empty variable; deckctl continued unauthenticated
That last one is the one that bites: private groups then look like they simply
have no templates. Check stderr.
export DECKCTL_WORK_TOKEN = glpat-xxxxxxxxxxxx
deckctl template list --source work
--tag was ignored. If the tag doesn’t exist on the project, deckctl warns
on stderr and uses the default branch. Check for
warning: tag "..." not found in project "...".
--tag on a local source. Local sources have no tags; the flag is ignored
silently.
A stale cache entry. Force a re-fetch:
deckctl template apply my-template ./out --source work --no-cache
# or evict just that entry
deckctl cache clear --source work --template my-template
Symptom Cause A variable was never prompted for It has a default in the sidecar. Defaults suppress the prompt — override with --var. {% if my_bool %} is true when I passed false--var values are strings, and "false" is a non-empty string. Use a sidecar default: false, or compare explicitly.Arithmetic on a number fails Same cause — --var port=8080 is the string "8080". --var seemed to do nothingThe entry had no = and was silently dropped. A choice variable accepted a value not in choices Prompts are free-text; choices is metadata, not enforcement at the prompt.
See Variables and prompting .
Error Fix variables delimiters must both be set or both emptyYou set variable_start without variable_end (or the block/comment equivalent). Set both or neither. variable of type "choice" requires choices to be setAdd choices, or change the type. N choices found, please set the variable type to "choice"You added choices to a str/int/bool variable. "foo" is not a valid typeValid types are str, int, bool, choice, or omitted.
Error Fix type must be 'local' or 'gitlab'Only those two source types exist. url is required / group is requiredBoth are mandatory on a gitlab source. path is requiredMandatory on a local source. token_env "..." must be uppercase letters, digits, or underscoresIt’s the name of an env var, not a token value. cache_ttl can't be set on local sourceLocal sources never cache. Remove the field. cache_ttl fails to parseGo duration syntax only — 24h, not 1d. duplicate source nameSource names must be unique.
Error Fix primary Color must be a valid hex colorUse #rgb or #rrggbb. Named colours are not supported. active theme "x" not found in themes listactive must match a name under themes.duplicate theme nameTheme names must be unique.
{{ }} in the output was replaced when it shouldn’t be. The file has a
template suffix, so it was rendered. Either drop the suffix (the file is then
copied verbatim) or change the delimiters. See
Custom delimiters .
A file wasn’t rendered at all. It has no suffix from
template_suffixes. Remember that setting template_suffixes replaces the
default list rather than extending it.
Nothing was applied from a Copier template. Check whether its copier.yml
sets _subdirectory — deckctl renders from there, not the repo root.
A deckctl.yaml and a copier.yml are both present and the wrong one is
being used. Native wins under auto; force with --sidecar-format copier.
# What does deckctl think the template expects?
deckctl template variables <name> --source <src>
# What would it actually write?
deckctl template apply <name> /tmp/out --source <src> --dry-run
# What did it do last time?
deckctl history list -o json
# What's cached, and how stale is it?
If the behaviour still doesn’t match this documentation, please
open an issue with the
command you ran, the stderr output, and deckctl --version.