{"record":{"id":"609276ea0211f02a","repo":"docker/compose","slug":"invalid-filter-filter","errorCode":null,"errorMessage":"invalid filter '${filter}'","messagePattern":"invalid filter '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/compose/list.go","lineNumber":91,"sourceCode":"\tfieldValues := filters[field]\n\tfor name2match := range fieldValues {\n\t\tisMatch, err := regexp.MatchString(name2match, source)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif isMatch {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc runList(ctx context.Context, dockerCli command.Cli, backendOptions *BackendOptions, lsOpts lsOptions) error {\n\tfilters := lsOpts.Filter.Value()\n\n\tfor filter := range filters {\n\t\tif _, ok := acceptedListFilters[filter]; !ok {\n\t\t\treturn errors.New(\"invalid filter '\" + filter + \"'\")\n\t\t}\n\t}\n\n\tbackend, err := compose.NewComposeService(dockerCli, backendOptions.Options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tstackList, err := backend.List(ctx, api.ListOptions{All: lsOpts.All})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(filters) > 0 {\n\t\tvar filtered []api.Stack\n\t\tfor _, s := range stackList {\n\t\t\tif match(filters, \"name\", s.Name) {\n\t\t\t\tfiltered = append(filtered, s)\n\t\t\t}","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/cmd/compose/list.go#L73-L109","documentation":"docker compose ls only supports a single filter key, \"name\" (defined in the acceptedListFilters map in cmd/compose/list.go). runList iterates over the parsed filter values and rejects any key not present in that map before contacting the backend. The error message interpolates the offending key, e.g. invalid filter 'status'.","triggerScenarios":"Running `docker compose ls --filter status=running`, `--filter project=foo`, or any KEY=VAL whose KEY is not exactly 'name'; note the flag is a strings slice, so `--filter name=foo` works while anything else fails.","commonSituations":"Users assuming docker compose ls shares filter keys with docker compose ps (status) or docker CLI (label, id); copy-pasting ps filter syntax into ls commands in scripts or docs.","solutions":["Use only the supported filter: `docker compose ls --filter name=<substring>`.","If you need to narrow by other attributes, filter client-side on the JSON output: `docker compose ls --format json | jq ...`.","Check for typos in the key name — the match is exact and case-sensitive."],"exampleFix":"# before\ndocker compose ls --filter status=running\n\n# after\ndocker compose ls --format json | jq '.[] | select(.State == \"running\")'","handlingStrategy":"validation","validationCode":"# only the 'name' key is accepted by docker compose ls --filter\nvalidate_ls_filter() {\n  case \"$1\" in\n    name=*) return 0 ;;\n    *) echo \"unsupported ls filter: $1 (only name=VAL)\" >&2; return 1 ;;\n  esac\n}\nvalidate_ls_filter \\\"$FILTER\\\" && docker compose ls --filter \\\"$FILTER\\\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember ls filters by name only; use --format json + jq for anything richer.","Do not copy ps/docker filter keys into ls commands."],"tags":["cli","ls","filter","validation"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}