Repository: ddev/ddev (go)

Issue:
`ddev snapshot` fails if  `--name`'s value includes spaces
### Preliminary checklist

- [x] I am using the latest stable version of DDEV (see [upgrade guide](https://ddev.readthedocs.io/en/stable/users/install/ddev-upgrade/))
- [x] I have searched [existing issues](https://github.com/ddev/ddev/issues)
- [x] I have checked the [troubleshooting guide](https://ddev.readthedocs.io/en/stable/users/usage/troubleshooting/)
- [x] I have run `ddev debug test` to include output below

### Output of `ddev debug test`

<details><summary>Expand `ddev debug test` diagnostic information</summary>
```



======== Output file will be in /tmp/ddev-debug-test.txt ========


======== Existing project config ========
ddev installation alternate locations:
/usr/bin/ddev
/bin/ddev

These config files were loaded for project sma-dec24: [/home/pc/dev/sma-dec24/.ddev/config.yaml]
name: sma-dec24
type: wordpress
php_version: 7.4
webserver_type: nginx-fpm
webimage: ddev/ddev-webserver:v1.24.2
additional_hostnames: []
additional_fqdns: []
database: {mariadb 10.11}
webimage_extra_packages: [python3 python-is-python3]
project_tld: ddev.site
use_dns_when_possible: true
composer_version: 2
nodejs_version: 22
default_container_timeout: 120


======== existing project customizations ========


======== installed DDEV add-ons ========
┌─────────┬─────────┬───────────────────┬──────────────────────┐
│ ADD-ON  │ VERSION │ REPOSITORY        │ DATE INSTALLED       │
├─────────┼─────────┼───────────────────┼──────────────────────┤
│ adminer │ v1.0.0  │ ddev/ddev-adminer │ 2024-12-21T04:27:55Z │
└─────────┴─────────┴───────────────────┴──────────────────────┘



======== mutagen situation ========
looking for #ddev-generated in mutagen.yml in project /home/pc/dev/sma-dec24
.ddev/mutagen/mutagen.yml not found


======== Creating dummy project named tryddevproject-14915 in ../tryddevproject-14915 ========
Creating a new DDEV project config in the current directory (/home/pc/dev/tryddevproject-14915)
Once completed, your configuration will be written to /home/pc/dev/tryddevproject-14915/.ddev/config.yaml

Created docroot directory at /home/pc/dev/tryddevproject-14915/web
Configuring a 'php' project named 'tryddevproject-14915' with docroot 'web' at '/home/pc/dev/tryddevproject-14915/web'.
For full details use 'ddev describe'.
Configuration complete. You may now run 'ddev start'.


======== OS Information ========
Linux windows 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux


======== User information ========
uid=1000(pc) gid=1000(pc) groups=1000(pc),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),107(netdev),989(docker)


======== DDEV version ========
 ITEM             VALUE
 DDEV version     v1.24.2
 architecture     amd64
 cgo_enabled      0
 db               ddev/ddev-dbserver-mariadb-10.11:v1.24.2
 ddev-ssh-agent   ddev/ddev-ssh-agent:v1.24.2
 docker           27.5.1
 docker-api       1.47
 docker-compose   v2.32.4
 docker-platform  wsl2-docker-ce
 global-ddev-dir  /home/pc/.ddev
 mutagen          0.18.0
 os               linux
 router           ddev/ddev-traefik-router:v1.24.2
 web              ddev/ddev-webserver:v1.24.2



======== proxy settings ========

 HTTP_PROXY=''
 HTTPS_PROXY=''
 http_proxy=''
 NO_PROXY=''



======== DDEV global info ========
developer-mode=false
fail-on-hook-fail=false
instrumentation-opt-in=true
instrumentation-queue-size=0
instrumentation-reporting-interval=0s
instrumentation-user=
internet-detection-timeout-ms=3000
last-started-version=v1.24.2
letsencrypt-email=
mailpit-http-port=8025
mailpit-https-port=8026
mkcert-caroot=/mnt/c/Users/pc/AppData/Local/mkcert
no-bind-mounts=false
omit-containers=[]
performance-mode=none
project-tld=ddev.site
required-docker-compose-version=v2.32.4
router-bind-all-interfaces=false
router-http-port=80
router-https-port=443
simple-formatting=false
table-style=default
traefik-monitor-port=10999
use-docker-compose-from-path=false
use-hardened-images=false
use-letsencrypt=false
wsl2-no-windows-hosts-mgt=false
xdebug-ide-location=


======== DOCKER provider info ========
docker client location: -rwxr-xr-x 1 root root 41798992 Jan 22 13:41 /usr/bin/docker

docker client alternate locations:
/usr/bin/docker
/bin/docker

Docker provider: wsl2-docker-ce
docker version:
Client: Docker Engine - Community
 Version:           27.5.1
 API version:       1.47
 Go version:        go1.22.11
 Git commit:        9f9e405
 Built:             Wed Jan 22 13:41:48 2025
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          27.5.1
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.22.11
  Git commit:       4c9b3b0
  Built:            Wed Jan 22 13:41:48 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.25
  GitCommit:        bcc810d6b9066471b0b6fa75f557a15a1cbf31bb
 runc:
  Version:          1.2.4
  GitCommit:        v1.2.4-0-g6c52b3f
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

DOCKER_DEFAULT_PLATFORM=notset
Docker platform: wsl2-docker-ce
Using Docker context: default (unix:///var/run/docker.sock)
docker-compose: v2.32.4
Using DOCKER_HOST=unix:///var/run/docker.sock
Docker version: 27.5.1
Able to run simple container that mounts a volume.
Able to use internet inside container.
Docker disk space:Filesystem                Size      Used Available Use% Mounted on
overlay                1006.9G     26.5G    929.2G   3% /


======== Existing docker containers ========
CONTAINER ID   IMAGE         COMMAND    CREATED       STATUS                   PORTS     NAMES
c86e95abb771   hello-world   "/hello"   8 weeks ago   Exited (0) 8 weeks ago             infallible_beaver
c81720d829d7   hello-world   "/hello"   8 weeks ago   Exited (0) 8 weeks ago             unruffled_solomon


======== mkcert information ========
/usr/local/bin/mkcert
/usr/bin/mkcert
/bin/mkcert
CAROOT=/mnt/c/Users/pc/AppData/Local/mkcert WSLENV=CAROOT/up: JAVA_HOME=
/mnt/c/Users/pc/AppData/Local/mkcert
total 8
-r-xr-xr-x 1 pc pc 2484 Dec  4 04:13 rootCA-key.pem
-rwxrwxrwx 1 pc pc 1647 Dec  4 04:13 rootCA.pem


======== ping attempt on ddev.site ========
PING dkdkd.ddev.site (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.058 ms

--- dkdkd.ddev.site ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.058/0.058/0.058/0.000 ms


======== curl information ========
/usr/bin/curl
/bin/curl


======== ddev debug rebuild ========
Rebuilding project images...
Rebuilding project tryddevproject-14915 with `/home/pc/.ddev/bin/docker-compose -f /home/pc/dev/tryddevproject-14915/.ddev/.ddev-docker-compose-full.yaml --progress plain build web --no-cache`
#0 building with "default" instance using docker driver

#1 [web internal] load build definition from Dockerfile
#1 transferring dockerfile: 1.53kB done
#1 DONE 0.0s

#2 [web internal] load metadata for docker.io/ddev/ddev-webserver:v1.24.2
#2 DONE 0.0s

#3 [web internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s

#4 [web  1/10] FROM docker.io/ddev/ddev-webserver:v1.24.2
#4 CACHED

#5 [web  2/10] RUN getent group tty || groupadd tty
#5 0.281 tty:x:5:
#5 DONE 0.3s

#6 [web  3/10] RUN (groupadd --gid 1000 "pc" || groupadd "pc" || true) && (useradd -G tty -l -m -s "/bin/bash" --gid "pc" --comment '' --uid 1000 "pc" || useradd -G tty -l -m -s "/bin/bash" --gid "pc" --comment '' "pc" || useradd  -G tty -l -m -s "/bin/bash" --gid "1000" --comment '' "pc" || useradd -G tty -l -m -s "/bin/bash" --comment '' pc )
#6 DONE 0.6s

#7 [web  4/10] RUN mkdir -p /home/pc && chown pc /home/pc && chmod 600 /home/pc/.pgpass
#7 DONE 0.5s

#8 [web  5/10] RUN START_SCRIPT_TIMEOUT=30 mariadb-client-install.sh || true
#8 0.440 This script is not intended to run with mariadb:10.11
#8 DONE 0.5s

#9 [web  6/10] RUN export XDEBUG_MODE=off; composer self-update --stable || composer self-update --stable || true; composer self-update --2 || log-stderr.sh composer self-update --2 || true
#9 0.735 Storing "stable" as default update channel for the next self-update run.
#9 0.952 Upgrading to version 2.8.5 (stable channel).
#9 0.969
#9 1.579 Use composer self-update --rollback to return to version 2.8.4
#9 1.428 You are already using the latest available Composer version 2.8.5 (2.x channel).
#9 DONE 1.5s

#10 [web  7/10] RUN timeout 30 apt-get update || true
#10 1.039 Get:1 http://nginx.org/packages/debian bookworm InRelease [2869 B]
#10 1.046 Get:2 http://deb.debian.org/debian bookworm InRelease [151 kB]
#10 1.092 Get:4 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]
#10 1.117 Get:5 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
#10 1.129 Get:6 https://packages.sury.org/php bookworm InRelease [7551 B]
#10 1.129 Get:7 http://nginx.org/packages/debian bookworm/nginx amd64 Packages [15.7 kB]
#10 1.148 Get:8 https://apt.postgresql.org/pub/repos/apt bookworm-pgdg InRelease [129 kB]
#10 1.151 Get:9 http://deb.debian.org/debian bookworm/main amd64 Packages [8792 kB]
#10 1.196 Get:10 https://dl.cloudsmith.io/public/platformsh/cli/deb/debian bookworm InRelease [3675 B]
#10 1.259 Get:11 https://packages.sury.org/php bookworm/main amd64 Packages [255 kB]
#10 1.363 Get:12 https://apt.postgresql.org/pub/repos/apt bookworm-pgdg/main amd64 Packages [360 kB]
#10 1.409 Get:13 https://dl.cloudsmith.io/public/platformsh/upsun-cli/deb/debian bookworm InRelease [3681 B]
#10 1.434 Get:3 https://dlm.mariadb.com/repo/mariadb-server/10.11/repo/debian bookworm InRelease [4625 B]
#10 1.601 Get:14 https://dl.cloudsmith.io/public/symfony/stable/deb/debian bookworm InRelease [4422 B]
#10 1.797 Get:15 https://dl.cloudsmith.io/public/platformsh/cli/deb/debian bookworm/main amd64 Packages [4504 B]
#10 1.915 Get:16 https://dl.cloudsmith.io/public/platformsh/upsun-cli/deb/debian bookworm/main amd64 Packages [3347 B]
#10 2.049 Get:18 https://dl.cloudsmith.io/public/symfony/stable/deb/debian bookworm/main amd64 Packages [8057 B]
#10 2.189 Get:17 https://dlm.mariadb.com/repo/mariadb-server/10.11/repo/debian bookworm/main amd64 Packages [41.2 kB]
#10 2.723 Get:19 https://dlm.mariadb.com/repo/mariadb-server/10.11/repo/debian bookworm/main arm64 Packages [34.5 kB]
#10 3.159 Get:20 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [13.5 kB]
#10 3.162 Get:21 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [243 kB]
#10 3.787 Fetched 10.2 MB in 3s (3116 kB/s)
#10 3.787 Reading package lists...
#10 DONE 4.2s

#11 [web  8/10] RUN curl -I https://www.google.com
#11 0.382   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
#11 0.382                                  Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
#11 0.441 HTTP/2 200
#11 0.441 content-type: text/html; charset=ISO-8859-1
#11 0.441 content-security-policy-report-only: object-src 'none';base-uri 'self';script-src 'nonce-br0BIrtYILgSKWoXmyq7ew' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
#11 0.441 accept-ch: Sec-CH-Prefers-Color-Scheme
#11 0.441 p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
#11 0.441 date: Sat, 01 Feb 2025 04:26:07 GMT
#11 0.441 server: gws
#11 0.441 x-xss-protection: 0
#11 0.441 x-frame-options: SAMEORIGIN
#11 0.441 expires: Sat, 01 Feb 2025 04:26:07 GMT
#11 0.441 cache-control: private
#11 0.441 set-cookie: AEC=AVcja2ctE_AQayIaSh-QO-9TTr7MsVjVLqYbODg7CTy1aCDLYqb4p7BdqQ; expires=Thu, 31-Jul-2025 04:26:07 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
#11 0.441 set-cookie: __Secure-ENID=25.SE=L_GUGwgwkvl37Pd4V6b60_udnVsUlnyFPVAmuj_BiFCoVnhIFaXTRBd-RkDV2fND6M7OjIJM2loPBC3XY8NmHloYlKWejCrMdNxvkUflRjA3M6Ca4M71QR-JzryIvyXNCpQxvtyErCBRQRldjJ1pHHQSh-RfT2E2rNkD-fBGfbm7K3C43cCkRuFr_g_X-RqwLMNQB_cn683yNgSq; expires=Tue, 03-Mar-2026 20:44:25 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
#11 0.441 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
#11 0.441
#11 DONE 0.5s

#12 [web  9/10] RUN chmod 777 /run/php /var/log
#12 DONE 0.5s

#13 [web 10/10] RUN mkdir -p /tmp/xhprof && chmod -R ugo+w /etc/php /var/lib/php /tmp/xhprof
#13 DONE 1.8s

#14 [web] exporting to image
#14 exporting layers
#14 exporting layers 0.3s done
#14 writing image sha256:9bb568c1949f45f0d73a8f467b7a70e20c87477946c42c6da6e46892d8ef1990 done
#14 naming to docker.io/ddev/ddev-webserver:v1.24.2-tryddevproject-14915-built 0.0s done
#14 DONE 0.3s

#15 [web] resolving provenance for metadata file
#15 DONE 0.0s
 web  Built
Rebuilt Docker cache for project tryddevproject-14915 in 12s
Network ddev_default created
 Container ddev-ssh-agent  Created
 Container ddev-ssh-agent  Started
ssh-agent container is running: If you want to add authentication to the ssh-agent container, run 'ddev auth ssh' to enable your keys.
Using custom web-build configuration: [
        /home/pc/dev/tryddevproject-14915/.ddev/web-build/Dockerfile.test
]
Custom configuration is updated on restart.
If you don't see your custom configuration taking effect, run 'ddev restart'.
Building project images....
Project images built in 2s.
 Network ddev-tryddevproject-14915_default  Created
 Container ddev-tryddevproject-14915-web  Created
 Container ddev-tryddevproject-14915-db  Created
 Container ddev-tryddevproject-14915-web  Started
 Container ddev-tryddevproject-14915-db  Started
Waiting for containers to become ready: [web db]
Starting ddev-router if necessary...
 Container ddev-router  Created
 Container ddev-router  Started


======== Project startup ========
Starting tryddevproject-14915...
2025-02-01T04:26:37.165 GetAvailableRouterPort(): Router is healthy and running
2025-02-01T04:26:37.166 GetAvailableRouterPort(): proposedPort 80 already bound on ddev-router, accepting it
2025-02-01T04:26:37.168 GetAvailableRouterPort(): Router is healthy and running
2025-02-01T04:26:37.17 GetAvailableRouterPort(): proposedPort 443 already bound on ddev-router, accepting it
2025-02-01T04:26:37.171 GetAvailableRouterPort(): Router is healthy and running
2025-02-01T04:26:37.173 GetAvailableRouterPort(): proposedPort 8025 already bound on ddev-router, accepting it
2025-02-01T04:26:37.174 GetAvailableRouterPort(): Router is healthy and running
2025-02-01T04:26:37.175 GetAvailableRouterPort(): proposedPort 8026 already bound on ddev-router, accepting it
2025-02-01T04:26:37.194 Pulled image for ddev/ddev-webserver:v1.24.2
2025-02-01T04:26:37.194 Pulled image for busybox:stable
2025-02-01T04:26:37.195 Pulled image for ddev/ddev-utilities
2025-02-01T04:26:37.196 Pulled image for ddev/ddev-ssh-agent:v1.24.2
2025-02-01T04:26:37.196 Pulled image for ddev/ddev-traefik-router:v1.24.2
2025-02-01T04:26:38.044 chowning /mnt/ddev-global-cache and /var/lib/mysql to 1000
2025-02-01T04:26:38.657 done chowning /mnt/ddev-global-cache and /var/lib/mysql to 1000
Using custom web-build configuration: [
        /home/pc/dev/tryddevproject-14915/.ddev/web-build/Dockerfile.test
]
Custom configuration is updated on restart.
If you don't see your custom configuration taking effect, run 'ddev restart'.
2025-02-01T04:26:38.678 host.docker.internal='172.18.144.1' because IsWSL2 and !IsDockerDesktop; received from ip -4 route show default
2025-02-01T04:26:38.695 Using automatically detected timezone: TZ=Europe/London
2025-02-01T04:26:38.778 Pulled image for ddev/ddev-webserver:v1.24.2
2025-02-01T04:26:38.779 Pulled image for ddev/ddev-dbserver-mariadb-10.11:v1.24.2
2025-02-01T04:26:38.78 Pulled image for ddev/ddev-traefik-router:v1.24.2
2025-02-01T04:26:38.78 Pulled image for ddev/ddev-ssh-agent:v1.24.2
Building project images...
2025-02-01T04:26:38.782 Executing docker-compose -f /home/pc/dev/tryddevproject-14915/.ddev/.ddev-docker-compose-full.yaml build --progress=plain
.
Project images built in 2s.
2025-02-01T04:26:40.486 Removing dangling images for the project ddev-tryddevproject-14915
2025-02-01T04:26:40.494 Executing docker-compose -f /home/pc/dev/tryddevproject-14915/.ddev/.ddev-docker-compose-full.yaml up -d
 Container ddev-tryddevproject-14915-db  Recreate
 Container ddev-tryddevproject-14915-web  Recreate
 Container ddev-tryddevproject-14915-db  Recreated
 Container ddev-tryddevproject-14915-web  Recreated
 Container ddev-tryddevproject-14915-web  Started
 Container ddev-tryddevproject-14915-db  Started
2025-02-01T04:26:51.903 VIRTUAL_HOST=tryddevproject-14915.ddev.site for web
2025-02-01T04:26:51.903 HTTP_EXPOSE=80:80,8025:8025 for web
2025-02-01T04:26:51.903 HTTPS_EXPOSE=443:80,8026:8025 for web
2025-02-01T04:26:52.412 Copied /home/pc/dev/tryddevproject-14915/.ddev/traefik:CopyIntoVolume_bbobsvnosiri into /mnt/v/traefik in 50.445277ms
2025-02-01T04:26:52.443 Exec chown -R 1000 /mnt/v/traefik stdout=, stderr=, err=<nil>
2025-02-01T04:26:52.745 Copied Traefik certs in /home/pc/dev/tryddevproject-14915/.ddev/traefik/certs to ddev-global-cache/traefik
2025-02-01T04:26:52.745 Running /start.sh in ddev-webserver
Waiting for containers to become ready: [web db]
2025-02-01T04:26:55.415 Copied /home/pc/.ddev/commands:CopyIntoVolume_dgsyjtgrlcvj into /mnt/v/global-commands in 47.06132ms
2025-02-01T04:26:55.444 Exec chown -R 1000 /mnt/v/global-commands stdout=, stderr=, err=<nil>
2025-02-01T04:26:55.887 Testing to see if /mnt/ddev_config is properly mounted
2025-02-01T04:26:56.01 Getting stderr output from 'log-stderr.sh --show'
Starting ddev-router if necessary...
2025-02-01T04:26:56.634 Copied /home/pc/.ddev/traefik:CopyIntoVolume_qcfiilwpvjof into /mnt/v/traefik in 33.907407ms
2025-02-01T04:26:56.667 Exec chown -R 1000 /mnt/v/traefik stdout=, stderr=, err=<nil>
2025-02-01T04:26:57.069 Copied global Traefik config in /home/pc/.ddev/traefik/certs to ddev-global-cache/traefik
 Container ddev-router  Running
2025-02-01T04:26:57.16 Waiting for ddev-router to become ready, timeout=60
2025-02-01T04:26:57.672 ddev-router is ready
Successfully started tryddevproject-14915
Your project can be reached at https://tryddevproject-14915.ddev.site
See 'ddev describe' for alternate URLs.


======== Curl of site from inside container ========
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 01 Feb 2025 04:27:02 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding



======== curl -I of http://127.0.0.1:32774 (web container http docker bind port) from outside ========
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 01 Feb 2025 04:27:02 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding



======== curl -I of http://tryddevproject-14915.ddev.site (router http URL) from outside ========
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Date: Sat, 01 Feb 2025 04:27:02 GMT
Server: nginx
Vary: Accept-Encoding



======== Full curl of http://tryddevproject-14915.ddev.site (router http URL) from outside ========
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   198    0   198    0     0  45112      0 --:--:-- --:--:-- --:--:-- 49500
Success accessing database... db via TCP/IP<br />
ddev is working.<br />
The output file for Discord or issue queue is in
<b>/tmp/ddev-debug-test.txt</b><br />
file:///tmp/ddev-debug-test.txt<br />


======== Full curl of https://tryddevproject-14915.ddev.site (router https URL) from outside ========
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   198    0   198    0     0   7757      0 --:--:-- --:--:-- --:--:--  7920
Success accessing database... db via TCP/IP<br />
ddev is working.<br />
The output file for Discord or issue queue is in
<b>/tmp/ddev-debug-test.txt</b><br />
file:///tmp/ddev-debug-test.txt<br />


======== Curl google.com to check internet access and VPN ========
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
HTTP/2 200
content-type: text/html; charset=ISO-8859-1
content-security-policy-report-only: object-src 'none';base-uri 'self';script-src 'nonce-HIFGMg19KSmBloPbwh8Mjw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
accept-ch: Sec-CH-Prefers-Color-Scheme
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
date: Sat, 01 Feb 2025 04:27:01 GMT
server: gws
x-xss-protection: 0
x-frame-options: SAMEORIGIN
expires: Sat, 01 Feb 2025 04:27:01 GMT
cache-control: private
set-cookie: AEC=AVcja2eS1v3TtZQqXMOFSZRfUMwRQwtj29rhqV2RRi2g_lhxEzZ3wWYg01A; expires=Thu, 31-Jul-2025 04:27:01 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
set-cookie: __Secure-ENID=25.SE=MUnkNMN-JSBoR9Fn6QV9kIO7DICfkkmyavLTImg84WViByxpBKr0_TW5GtPT_LuTo082GxdTXzJPUCALAs3FnYjoNbSDTzlCpFLDBZkA-7HsxQfuA6iaKOr3FgNcKBAiLPCcBxnJ8hykAdYiIbagfN3v8pbYQzLmrvZDoh1slKP535DQNde_Qy3uRGx3XjevQc_IKiTMhact15yGjg; expires=Tue, 03-Mar-2026 20:45:19 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000



======== host.docker.internal status ========
PING host.docker.internal (172.18.144.1) 56(84) bytes of data.
64 bytes from host.docker.internal (172.18.144.1): icmp_seq=1 ttl=127 time=0.261 ms

--- host.docker.internal ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.261/0.261/0.261/0.000 ms


======== Project ownership on host ========
drwxr-xr-x 4 pc pc 4096 Feb  1 04:25 ../tryddevproject-14915


======== Project ownership in container ========
drwxr-xr-x 4 pc pc 4096 Feb  1 04:25 //var/www/html


======== In-container filesystem ========
Filesystem     Type  1K-blocks     Used Available Use% Mounted on
/dev/sdc       ext4 1055762868 27905432 974153964   3% /var/www/html


======== Thanks for running the diagnostic! ========
Running ddev launch in 3 seconds
Running ddev launch
Waiting for ddev launch to complete before deleting project


Cleanup: deleting test project tryddevproject-14915
 Container ddev-tryddevproject-14915-db  Stopped
 Container ddev-tryddevproject-14915-web  Stopped
 Container ddev-tryddevproject-14915-db  Stopped
 Container ddev-tryddevproject-14915-web  Stopped
 Container ddev-tryddevproject-14915-db  Removed
 Container ddev-tryddevproject-14915-web  Removed
 Network ddev-tryddevproject-14915_default  Removed
Volume tryddevproject-14915-mariadb for project tryddevproject-14915 was deleted
Volume tryddevproject-14915-postgres for project tryddevproject-14915 was deleted
Volume tryddevproject-14915_project_mutagen for project tryddevproject-14915 was deleted
Project tryddevproject-14915 was deleted. Your code and configuration are unchanged.

Please remove the files from this test with 'rm -r ../tryddevproject-14915'
```
</details>


### Expected Behavior

I ran `ddev snapshot --name="Removed dependency on WCM"` without thinking too much about it, to be greeted with a grizzly error message which didn't seem intended or expected. When I re-ran `ddev snapshot --name=remove_wcm_dependency` it worked as expected.

My request here is a humble ask for a error message to the operator which clarifies that spaces/`"` symbols cannot be used in snapshot names, to be more clear and upfront about why ddev isn't doing what is expected.

It appears that ddev started to create the snapshot with the name I gave it then something went wrong. I therefore consider it a valid bug due to the lack of graceful handling explaining to the operator that they can't use either/or spaces or `"` in a snapshot's name (I'm not sure which of the two messed it up here).


### Actual Behavior

Upon running the initial command `ddev snapshot --name="Repairing after WCM removal"`, I got the following output to my terminal:

<details><summary>
```
Creating database snapshot Repairing after WCM removal
Failed to create snapshot: composeCmd failed to run 'COMPOSE_PROJECT_NAME=ddev-sma-dec24 docker-compose -f /home/pc/dev/sma-dec24/.ddev/.ddev-docker-compose-full.yaml exec -T db bash -c set -eu && ( set -eu -o pipefail; mariabackup --backup --stream=mbstream --user=root --password=root --socket=/var/tmp/mysql.sock  2>/tmp/snapshot_Repairing after WCM removal-mariadb_10.11.gz.log | gzip > "/var/tmp/Repairing after WCM removal-mariadb_10.11.gz" )', action='[exec -T db bash -c set -eu && ( set -eu -o pipefail; mariabackup --backup --stream=mbstream --user=root --password=root --socket=/var/tmp/mysql.sock  2>/tmp/snapshot_Repairing after WCM removal-mariadb_10.11.gz.log | gzip > "/var/tmp/Repairing after WCM removal-mariadb_10.11.gz" )]', err='exit status 1', stdout='', stderr='', stdout=, stderr=
Failed to snapshot sma-dec24: composeCmd failed to run 'COMPOSE_PROJECT_NAME=ddev-sma-dec24 docker-compose -f /home/pc/dev/sma-dec24/.ddev/.ddev-docker-compose-full.yaml exec -T db bash -c set -eu && ( set -eu -o pipefail; mariabackup --backup --stream=mbstream --user=root --password=root --socket=/var/tmp/mysql.sock  2>/tmp/snapshot_Repairing after WCM removal-mariadb_10.11.gz.log | gzip > "/var/tmp/Repairing after WCM removal-mariadb_10.11.gz" )', action='[exec -T db bash -c set -eu && ( set -eu -o pipefail; mariabackup --backup --stream=mbstream --user=root --password=root --socket=/var/tmp/mysql.sock  2>/tmp/snapshot_Repairing after WCM removal-mariadb_10.11.gz.log | gzip > "/var/tmp/Repairing after WCM removal-mariadb_10.11.gz" )]', err='exit status 1', stdout='', stderr=''
```
</summary></details>

### Steps To Reproduce

1. As far as I can tell, this should work in any image. Mine specifically was running a WordPress v6.7.1 image in PHP v7.4.33, latest ddev (1.24.2 under Windows in WSL2).
2. Within the command line, `cd` to the working directory then attempt to execute `ddev snapshot --name="This will not work"`
3. ddev should throw an error in attempting to create a snapshot with an invalid name.


### Anything else?

You can also see this attached as an image, which shows both my failed attempt and successful one. This is in Windows Terminal running under Windows 10, fwiw:

![Image](https://github.com/user-attachments/assets/384e2b97-e3d1-4b8d-ad66-54ebcac190ae)

Pull request description:
fix: check snapshot name for valid characters, fixes #6955
## The Issue

- #6955

## How This PR Solves The Issue

Checks if the snapshot title contains letters, numbers, hyphens, or underscores.

Instead, we could escape or replace incorrect characters, but the validation is simpler.

## Manual Testing Instructions

```
ddev snapshot --name="with spaces"
Failed to snapshot d11: invalid snapshot name 'with spaces': it may only contain letters, numbers, hyphens, periods, and underscores
```

```
ddev snapshot --name="single'quotes"
Failed to snapshot d11: invalid snapshot name 'single'quotes': it may only contain letters, numbers, hyphens, periods, and underscores
```

```
ddev snapshot --name="double\"quotes"
Failed to snapshot d11: invalid snapshot name 'double"quotes': it may only contain letters, numbers, hyphens, periods, and underscores
```

```
ddev snapshot --name="my_snapshot-123-test.name"
Creating database snapshot my_snapshot-123-test.name
Created database snapshot my_snapshot-123-test.name 
Restore this snapshot with 'ddev snapshot restore my_snapshot-123-test.name'
```

## Automated Testing Overview

<!-- Please describe the tests introduced by this PR, or explain why no tests are needed. -->

## Release/Deployment Notes

<!-- Does this affect anything else or have ramifications for other code? Does anything have to be done on deployment? -->


Patch:
diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml
index 5317ce719..306b5d764 100644
--- a/.github/workflows/docspublish.yml
+++ b/.github/workflows/docspublish.yml
@@ -12,7 +12,7 @@ jobs:
       - uses: actions/checkout@v4
         with:
           fetch-depth: 0
-      - uses: actions/setup-python@v5.3.0
+      - uses: actions/setup-python@v5.4.0
         with:
           python-version: 3.x
       - run: echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
diff --git a/cmd/ddev/cmd/import-files.go b/cmd/ddev/cmd/import-files.go
index ea45b256c..505454174 100644
--- a/cmd/ddev/cmd/import-files.go
+++ b/cmd/ddev/cmd/import-files.go
@@ -133,7 +133,7 @@ func promptForFileSource(val *string) {
 	// prompting until something is entered
 	for {
 		fmt.Print("Path to file(s): ")
-		*val = util.GetInput("")
+		*val = util.GetQuotedInput("")
 		if len(*val) > 0 {
 			break
 		}
@@ -150,7 +150,7 @@ func promptForExtractPath(val *string) {
 	// An empty string is acceptable in this case, indicating
 	// no particular extraction path
 	fmt.Print("Archive extraction path: ")
-	*val = util.GetInput("")
+	*val = util.GetQuotedInput("")
 }
 
 func init() {
diff --git a/cmd/ddev/cmd/utils.go b/cmd/ddev/cmd/utils.go
index 8053b0edc..192955e7a 100644
--- a/cmd/ddev/cmd/utils.go
+++ b/cmd/ddev/cmd/utils.go
@@ -124,7 +124,7 @@ func GetUnknownFlags(cmd *cobra.Command) (map[string]string, error) {
 		if !flagRegex.MatchString(arg) {
 			// Fail if the value is not a valid flag
 			if strings.HasPrefix(arg, "-") {
-				return unknownFlags, fmt.Errorf("the flag must be lowercase and start with a letter, but received %s", arg)
+				return unknownFlags, fmt.Errorf("the flag must consist of lowercase letters, numbers, and hyphens, and it must start with a letter, but received %s", arg)
 			}
 			// Skip if the value is not a flag, but an argument
 			continue
diff --git a/pkg/ddevapp/ddevapp.go b/pkg/ddevapp/ddevapp.go
index 7f43bd8b5..d15fdb198 100644
--- a/pkg/ddevapp/ddevapp.go
+++ b/pkg/ddevapp/ddevapp.go
@@ -7,6 +7,7 @@ import (
 	"os"
 	"path"
 	"path/filepath"
+	"regexp"
 	"runtime"
 	"slices"
 	"sort"
@@ -736,7 +737,7 @@ func (app *DdevApp) ImportDB(dumpFile string, extractPath string, progress bool,
 		output.UserOut.Println("Provide the path to the database you want to import.")
 		fmt.Print("Path to file: ")
 
-		dumpFile = util.GetInput("")
+		dumpFile = util.GetQuotedInput("")
 	}
 
 	if dumpFile != "" {
@@ -746,7 +747,7 @@ func (app *DdevApp) ImportDB(dumpFile string, extractPath string, progress bool,
 				output.UserOut.Println("You provided an archive. Do you want to extract from a specific path in your archive? You may leave this blank if you wish to use the full archive contents")
 				fmt.Print("Archive extraction path:")
 
-				extractPath = util.GetInput("")
+				extractPath = util.GetQuotedInput("")
 			} else {
 				return fmt.Errorf("unable to validate import asset %s: %s", dumpFile, err)
 			}
@@ -2654,6 +2655,10 @@ func (app *DdevApp) Snapshot(snapshotName string) (string, error) {
 		snapshotName = app.Name + "_" + t.Format("20060102150405")
 	}
 
+	if !regexp.MustCompile(`^[\w-.]+$`).MatchString(snapshotName) {
+		return "", fmt.Errorf("invalid snapshot name '%s': it may only contain letters, numbers, hyphens, periods, and underscores", snapshotName)
+	}
+
 	snapshotFile := snapshotName + "-" + app.Database.Type + "_" + app.Database.Version + ".gz"
 
 	existingSnapshots, err := app.ListSnapshotNames()
diff --git a/pkg/util/prompt.go b/pkg/util/prompt.go
index 6fbf6dfd6..93367136f 100644
--- a/pkg/util/prompt.go
+++ b/pkg/util/prompt.go
@@ -28,6 +28,19 @@ func GetInput(defaultValue string) string {
 	return value
 }
 
+// GetQuotedInput reads input from an input buffer in single or double quotes and returns the result as a string.
+func GetQuotedInput(defaultValue string) string {
+	input := GetInput(defaultValue)
+
+	// If the value from the input buffer is blank, then use the default instead.
+	value := strings.Trim(input, `"' `)
+	if value == "" {
+		value = defaultValue
+	}
+
+	return value
+}
+
 // Prompt gets input with a prompt and returns the input
 func Prompt(prompt string, defaultValue string) string {
 	fullPrompt := fmt.Sprintf("%s (%s)", prompt, defaultValue)


Test patch:
diff --git a/cmd/ddev/cmd/dotenv_test.go b/cmd/ddev/cmd/dotenv_test.go
index 12962468a..ecb77bcaa 100644
--- a/cmd/ddev/cmd/dotenv_test.go
+++ b/cmd/ddev/cmd/dotenv_test.go
@@ -81,11 +81,11 @@ func TestCmdDotEnvGetAndSet(t *testing.T) {
 
 	out, err = exec.RunHostCommand(DdevBin, "dotenv", "set", envFile, "--TEST", "custom value")
 	require.Error(t, err, "out=%s", out)
-	require.Contains(t, out, "the flag must be lowercase and start with a letter")
+	require.Contains(t, out, "the flag must consist of lowercase letters, numbers, and hyphens")
 
 	out, err = exec.RunHostCommand(DdevBin, "dotenv", "set", envFile, "--1test", "custom value")
 	require.Error(t, err, "out=%s", out)
-	require.Contains(t, out, "the flag must be lowercase and start with a letter")
+	require.Contains(t, out, "the flag must consist of lowercase letters, numbers, and hyphens")
 
 	out, err = exec.RunHostCommand(DdevBin, "dotenv", "get", envFile, "--test-value", "--test-value-2")
 	require.Error(t, err, "out=%s", out)
diff --git a/pkg/ddevapp/snapshot_test.go b/pkg/ddevapp/snapshot_test.go
index c280c3804..73574ea85 100644
--- a/pkg/ddevapp/snapshot_test.go
+++ b/pkg/ddevapp/snapshot_test.go
@@ -198,6 +198,19 @@ func TestDdevRestoreSnapshot(t *testing.T) {
 	_, err = app.Snapshot("d7testerTest1")
 	assert.Error(err)
 
+	// Name should contain only allowed characters
+	_, err = app.Snapshot(`name with spaces`)
+	require.Error(t, err)
+	require.Contains(t, err.Error(), "invalid snapshot name")
+
+	_, err = app.Snapshot(`single'quotes`)
+	require.Error(t, err)
+	require.Contains(t, err.Error(), "invalid snapshot name")
+
+	_, err = app.Snapshot(`double"quotes`)
+	require.Error(t, err)
+	require.Contains(t, err.Error(), "invalid snapshot name")
+
 	err = app.ImportDB(d7testerTest2Dump, "", false, false, "db")
 	assert.NoError(err, "Failed to app.ImportDB path: %s err: %v", d7testerTest2Dump, err)
 
diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go
index a36a93023..308663198 100644
--- a/pkg/util/utils_test.go
+++ b/pkg/util/utils_test.go
@@ -63,6 +63,32 @@ func TestGetInput(t *testing.T) {
 	println() // Just lets goland find the PASS or FAIL
 }
 
+// TestGetQuotedInput tests GetQuotedInput
+func TestGetQuotedInput(t *testing.T) {
+	testCases := []struct {
+		description string
+		input       string
+		expected    string
+	}{
+		{"Remove single quotes", `'/path/to/file'`, `/path/to/file`},
+		{"Remove double quotes", `"/path/to/file"`, `/path/to/file`},
+		{"Remove spaces", `  /path/to/file  `, `/path/to/file`},
+		{"Remove all quotes and spaces", `  ''' """ /path/to/file '''  """ `, `/path/to/file`},
+		{"Quotes and spaces are not removed from the middle", `/path/'" to/file`, `/path/'" to/file`},
+	}
+	for _, tc := range testCases {
+		t.Run(tc.description, func(t *testing.T) {
+			assert := asrt.New(t)
+			restoreOutput := util.CaptureUserOut()
+			scanner := bufio.NewScanner(strings.NewReader(tc.input))
+			util.SetInputScanner(scanner)
+			result := util.GetQuotedInput("nodefault")
+			assert.EqualValues(tc.expected, result)
+			_ = restoreOutput()
+		})
+	}
+}
+
 // TestCaptureUserOut ensures capturing of stdout works as expected.
 func TestCaptureUserOut(t *testing.T) {
 	assert := asrt.New(t)