coollabsio/coolify · error · RuntimeException

Invalid {$fieldName}: contains forbidden shell characters.

Error message

Invalid {$fieldName}: contains forbidden shell characters.

What it means

validateShellSafeCommand() enforces ValidationPatterns::SHELL_SAFE_COMMAND_PATTERN — a token-aware regex allowing whitespace, && and ||, balanced quoted strings, and safe unquoted tokens; it blocks bare & | ; $ ` ( ) < > \ newlines, unbalanced quotes, and $/backtick inside double quotes. It is applied to user-supplied command/option strings (docker compose commands, docker run options) before they are executed during deployment, preventing shell injection.

Source

Thrown at app/Jobs/ApplicationDeploymentJob.php:4688

        return $composeFile;
    }

    private function validatePathField(string $value, string $fieldName): string
    {
        if (! preg_match(ValidationPatterns::FILE_PATH_PATTERN, $value)) {
            throw new \RuntimeException("Invalid {$fieldName}: contains forbidden characters.");
        }
        if (str_contains($value, '..')) {
            throw new \RuntimeException("Invalid {$fieldName}: path traversal detected.");
        }

        return $value;
    }

    private function validateShellSafeCommand(string $value, string $fieldName): string
    {
        if (! preg_match(ValidationPatterns::SHELL_SAFE_COMMAND_PATTERN, $value)) {
            throw new \RuntimeException("Invalid {$fieldName}: contains forbidden shell characters.");
        }

        return $value;
    }

    private function validateContainerName(string $value): string
    {
        if (! preg_match(ValidationPatterns::CONTAINER_NAME_PATTERN, $value)) {
            throw new \RuntimeException('Invalid container name: contains forbidden characters.');
        }

        return $value;
    }

    /**
     * Resolve which container to execute a deployment command in.
     *
     * For single-container apps, returns the sole container.

View on GitHub (pinned to 70b9acc424)

Solutions

  1. Remove shell expansions: no $VAR, no backticks, no $(...) — pass values as Docker environment variables / env_file instead.
  2. Keep only && or || as separators; never ';' or single '&'.
  3. Wrap arguments with spaces in balanced double quotes (with no $ inside) or single quotes.
  4. Test the value against the pattern before saving: preg_match(ValidationPatterns::SHELL_SAFE_COMMAND_PATTERN, $value).

Example fix

# before: expansion and semicolon blocked
command: 'echo $TOKEN; ./migrate --pw=$(cat /run/secret)'

# after: safe tokens only, secrets via env
dockerfileLocation unchanged; command: 'echo token-set && ./migrate --pw-file /run/secret'
# TOKEN injected as a container environment variable instead
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate command/option strings with the same pattern the deploy job uses
if (! preg_match(\App\Support\ValidationPatterns::SHELL_SAFE_COMMAND_PATTERN, $value)) {
    throw new \InvalidArgumentException('Command contains forbidden shell characters (bare & | ; $ ` ( ) < > \\, unbalanced quotes).');
}

Type guard

function isShellSafeCommand(?string $value): bool
{
    return blank($value)
        || preg_match(\App\Support\ValidationPatterns::SHELL_SAFE_COMMAND_PATTERN, $value) === 1;
}

Prevention

When it happens

Trigger: A command field contains command substitution ('$(curl ...)'), variable expansion ('$PASSWORD'), statement separators (';', newline), a single '&', parentheses, or an unbalanced quote; any of these in the value passed to validateShellSafeCommand() during the deploy job.

Common situations: Users pasting shell one-liners into command option fields; attempting 'echo $FOO && cmd'; entries with a stray unmatched quote from manual editing; trying to background a process with '&'.

Understand the failure class

Related errors


AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17). Data as JSON: /api/errors/e89b0cd4f258b3bb. Report an issue: GitHub.