{"record":{"id":"45acec902c7dc5d6","repo":"nektos/act","slug":"health-start-interval-cannot-be-negative","errorCode":null,"errorMessage":"--health-start-interval cannot be negative","messagePattern":"--health-start-interval cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/container/docker_cli.go","lineNumber":598,"sourceCode":"\t} else if haveHealthSettings {\n\t\tvar probe []string\n\t\tif copts.healthCmd != \"\" {\n\t\t\tprobe = []string{\"CMD-SHELL\", copts.healthCmd}\n\t\t}\n\t\tif copts.healthInterval < 0 {\n\t\t\treturn nil, errors.New(\"--health-interval cannot be negative\")\n\t\t}\n\t\tif copts.healthTimeout < 0 {\n\t\t\treturn nil, errors.New(\"--health-timeout cannot be negative\")\n\t\t}\n\t\tif copts.healthRetries < 0 {\n\t\t\treturn nil, errors.New(\"--health-retries cannot be negative\")\n\t\t}\n\t\tif copts.healthStartPeriod < 0 {\n\t\t\treturn nil, errors.New(\"--health-start-period cannot be negative\")\n\t\t}\n\t\tif copts.healthStartInterval < 0 {\n\t\t\treturn nil, errors.New(\"--health-start-interval cannot be negative\")\n\t\t}\n\n\t\thealthConfig = &container.HealthConfig{\n\t\t\tTest:          probe,\n\t\t\tInterval:      copts.healthInterval,\n\t\t\tTimeout:       copts.healthTimeout,\n\t\t\tStartPeriod:   copts.healthStartPeriod,\n\t\t\tStartInterval: copts.healthStartInterval,\n\t\t\tRetries:       copts.healthRetries,\n\t\t}\n\t}\n\n\tdeviceRequests := copts.gpus.Value()\n\tif len(cdiDeviceNames) > 0 {\n\t\tcdiDeviceRequest := container.DeviceRequest{\n\t\t\tDriver:    \"cdi\",\n\t\t\tDeviceIDs: cdiDeviceNames,\n\t\t}","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/container/docker_cli.go#L580-L616","documentation":"Error [90]: Before copying a tar stream into the container at destPath, act first sends a synthetic tar directory entry to '/' via CopyToContainer to create the destination directory. That mkdir-by-tar API call failed. Causes: container not running, daemon error during upload, or filesystem errors in the container (read-only rootfs, full disk).","triggerScenarios":"cr.cli.CopyToContainer with the TypeDir tar header failing: target container exited/paused between exec and copy, container root filesystem is read-only (readonly rootfs in options), disk full inside container, or API/stream error to daemon.","commonSituations":"Actions like actions/checkout or file-copy steps against a job container that crashed earlier; --container-options with --read-only; overlay2 disk exhaustion on the host; container in 'Dead' state after OOM.","solutions":["Check container state: docker ps -a --filter name=act — restart/freed? then inspect logs for the crash cause","Remove '--read-only' from container options if present","Check host disk space: df -h (overlay2 lives on host)","Re-run after cleaning leftover containers: docker rm -f $(docker ps -aq --filter name=act-)"],"exampleFix":"# before\nact --container-options \"--read-only\"\n# after\nact --container-options \"\"","handlingStrategy":"validation","validationCode":"// Verify container is running and writable before copying\ninfo, _ := cli.ContainerInspect(ctx, id)\nif !info.State.Running { return errors.New(\"container not running\") }\nif info.HostConfig != nil && info.HostConfig.ReadonlyRootfs { return errors.New(\"rootfs read-only\") }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to mkdir to copy content\") {\n\t// inspect container state + logs; readonly rootfs and dead containers are the usual causes\n}","preventionTips":["Don't pass --read-only in container options to act","Free host disk before large jobs (df -h)","Clean dead act containers between runs"],"tags":["docker","copy","tar","filesystem","container-lifecycle"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}