{"record":{"id":"6bf48bd174de64a8","repo":"nektos/act","slug":"invalid-storage-option","errorCode":null,"errorMessage":"invalid storage option","messagePattern":"invalid storage option","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/container/docker_cli.go","lineNumber":994,"sourceCode":"\tfor _, opt := range securityOpts {\n\t\tif opt == \"systempaths=unconfined\" {\n\t\t\tmaskedPaths = []string{}\n\t\t\treadonlyPaths = []string{}\n\t\t} else {\n\t\t\tfiltered = append(filtered, opt)\n\t\t}\n\t}\n\n\treturn filtered, maskedPaths, readonlyPaths\n}\n\n// parses storage options per container into a map\nfunc parseStorageOpts(storageOpts []string) (map[string]string, error) {\n\tm := make(map[string]string)\n\tfor _, option := range storageOpts {\n\t\tk, v, ok := strings.Cut(option, \"=\")\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"invalid storage option\")\n\t\t}\n\t\tm[k] = v\n\t}\n\treturn m, nil\n}\n\n// parseDevice parses a device mapping string to a container.DeviceMapping struct\nfunc parseDevice(device, serverOS string) (container.DeviceMapping, error) {\n\tswitch serverOS {\n\tcase \"linux\":\n\t\treturn parseLinuxDevice(device)\n\tcase \"windows\":\n\t\t// Windows doesn't support mapping, so passing the given value as-is.\n\t\treturn container.DeviceMapping{PathOnHost: device}, nil\n\tdefault:\n\t\treturn container.DeviceMapping{}, fmt.Errorf(\"unknown server OS: %s\", serverOS)\n\t}\n}","sourceCodeStart":976,"sourceCodeEnd":1012,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/container/docker_cli.go#L976-L1012","documentation":"parseStorageOpts splits each --storage-opt entry on the first '=' using strings.Cut; an entry without an '=' character cannot form a key/value pair and is rejected outright with 'invalid storage option'. This mirrors the Docker CLI's own validation, so anything docker run would reject also fails at act's parse layer before the container is created.","triggerScenarios":"A container options string containing a bare flag-style storage option, e.g. 'options: --storage-opt size' (missing '=10G'), or a trailing empty entry like '--storage-opt ' after shell-style splitting. Any element of the parsed storageOpts slice that contains no '=' character.","commonSituations":"Typing '--storage-opt size' instead of '--storage-opt size=10G' on overlay2/btrfs/zfs drivers; copy-pasting options where the value was dropped; quoting mistakes in YAML that strip the '=value' part during shell-like splitting of the options line.","solutions":["Rewrite the option in key=value form: '--storage-opt size=10G'.","Verify YAML quoting of the options line so '=' survives parsing (quote the whole string in single quotes).","Confirm the key is valid for your storage driver (size only works on overlay2 with pquota, btrfs, zfs, devicethrow); an invalid key with correct syntax will instead be rejected by the daemon.","Remove stray/duplicate --storage-opt flags that parse to empty strings."],"exampleFix":"# before\ncontainer:\n  image: node:20\n  options: --storage-opt size\n\n# after\ncontainer:\n  image: node:20\n  options: --storage-opt size=10G","handlingStrategy":"validation","validationCode":"package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc validateStorageOpts(options string) error {\n\tfor i, f := range strings.Fields(options) {\n\t\tif f == \"--storage-opt\" {\n\t\t\tif i+1 >= len(strings.Fields(options)) || !strings.Contains(strings.Fields(options)[i+1], \"=\") {\n\t\t\t\treturn fmt.Errorf(\"--storage-opt requires key=value (got no '=' in next token)\")\n\t\t\t}\n\t\t}\n\t\tif v, ok := strings.CutPrefix(f, \"--storage-opt=\"); ok && !strings.Contains(v, \"=\") {\n\t\t\treturn fmt.Errorf(\"--storage-opt=%q lacks '='\", v)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := exec.NewContainerExecutor(...)(ctx); err != nil {\n    if strings.Contains(err.Error(), \"invalid storage option\") {\n        return fmt.Errorf(\"fix container options: each --storage-opt must be key=value: %w\", err)\n    }\n    return err\n}","preventionTips":["Always write storage options as --storage-opt key=value.","Quote the full options string in YAML so '=' survives parsing.","Confirm the key is supported by your storage driver (size works on overlay2+pquota, btrfs, zfs)."],"tags":["docker","storage","container-options","validation"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}