{"record":{"id":"4c18a356b55f8ad2","repo":"nektos/act","slug":"cannot-split-container-options-s-w","errorCode":null,"errorMessage":"Cannot split container options: '%s': '%w'","messagePattern":"Cannot split container options: '(.+?)': '%w'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/container/docker_run.go","lineNumber":368,"sourceCode":"\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) mergeContainerConfigs(ctx context.Context, config *container.Config, hostConfig *container.HostConfig) (*container.Config, *container.HostConfig, error) {\n\tlogger := common.Logger(ctx)\n\tinput := cr.input\n\n\tif input.Options == \"\" {\n\t\treturn config, hostConfig, nil\n\t}\n\n\t// parse configuration from CLI container.options\n\tflags := pflag.NewFlagSet(\"container_flags\", pflag.ContinueOnError)\n\tcopts := addFlags(flags)\n\n\toptionsArgs, err := shellquote.Split(input.Options)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot split container options: '%s': '%w'\", input.Options, err)\n\t}\n\n\terr = flags.Parse(optionsArgs)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot parse container options: '%s': '%w'\", input.Options, err)\n\t}\n\n\tif len(copts.netMode.Value()) == 0 {\n\t\tif err = copts.netMode.Set(cr.input.NetworkMode); err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"Cannot parse networkmode=%s. This is an internal error and should not happen: '%w'\", cr.input.NetworkMode, err)\n\t\t}\n\t}\n\n\tcontainerConfig, err := parse(flags, copts, runtime.GOOS)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot process container options: '%s': '%w'\", input.Options, err)\n\t}\n","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/container/docker_run.go#L350-L386","documentation":"mergeContainerConfigs parses the job's container options string with shellquote.Split before feeding them to a pflag FlagSet. If shell-style tokenization fails — unbalanced quotes or backslashes — the options cannot even be split into arguments and this error names the raw option string.","triggerScenarios":"A container: options: value (or --container-options flag) with an unterminated single/double quote, trailing backslash, or otherwise invalid shell quoting, e.g. options: --cpus 2=\" or --shm-size=\"1g.","commonSituations":"Hand-writing YAML options lines and losing a closing quote; escaping rules differ between YAML, shell, and pflag so a value that worked in docker run CLI breaks when embedded in the workflow.","solutions":["Balance all quotes in the options string; prefer single-word values that need no quoting","Test tokenization locally: echo <options> | xargs -n1 echo (or shellquote in Go)","Simplify: move complex settings into act flags (--container-options) or dedicated workflow fields where available"],"exampleFix":"# before\ncontainer:\n  image: node:20\n  options: --shm-size=\"1g\n\n# after\ncontainer:\n  image: node:20\n  options: --shm-size=1g","handlingStrategy":"validation","validationCode":"# shell: verify the options string tokenizes cleanly\nprintf '%s' \"$OPTIONS\" | xargs -n1 echo >/dev/null || echo \"unbalanced quoting in options\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid quotes in container.options entirely — prefer flag=value form","Keep options on one YAML line with no manual shell escaping","Validate option strings in a workflow-lint CI step"],"tags":["docker","container-options","quoting","shell-parsing","workflow-config"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}